Skip to content

Instantly share code, notes, and snippets.

@hidez8891
Last active February 7, 2021 04:11
Show Gist options
  • Save hidez8891/085057eb94e9750b2b4f74da5da52414 to your computer and use it in GitHub Desktop.
Save hidez8891/085057eb94e9750b2b4f74da5da52414 to your computer and use it in GitHub Desktop.
継承とインターフェイスによる、template引数の制限 (C++20)
#include <iostream>
#include <fstream>
#include <type_traits>
#include <cassert>
// 継承関係で制限
template <class T, class U>
concept Derived = std::is_base_of<U, T>::value;
template <typename IStream, typename OStream>
requires Derived<IStream, std::basic_istream<typename IStream::char_type>>
&& Derived<OStream, std::basic_ostream<typename OStream::char_type>>
void copy(IStream in, OStream out){}
// インターフェイスで制限 Part1
template <class T>
concept Reader = requires(T t){
{ t.read(new(char)) } -> std::same_as<int>;
};
template <class T>
concept Writer = requires(T t){
{ t.write(new(char)) } -> std::same_as<int>;
};
struct FakeReader {
int read(char* buf){ return 0; }
};
struct FakeWriter {
int write(char* buf){ return 0; }
};
template <Reader ReadT, Writer WriteT>
void copy(ReadT r, WriteT w){}
// インターフェイスで制限 Part2
template <class T>
concept Scanner = requires(T t){
std::is_same<decltype(&T::scan), int(T::*)(char*)>::value;
};
template <class T>
concept Printer = requires(T t){
std::is_same<decltype(&T::print), int(T::*)(char*)>::value;
};
struct FakeScanner {
int scan(char* buf){ return 0; }
};
struct FakePrinter {
int print(char* buf){ return 0; }
};
template <Scanner ScanT, Printer PrintT>
void copy(ScanT s, PrintT p){}
// main
int main() {
copy(std::ifstream{}, std::wofstream{});
copy(FakeReader{}, FakeWriter{});
copy(FakeScanner{}, FakePrinter{});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment