#include <iostream>
#include <type_traits>
using namespace std;
template<class T>
struct Base {
string name = "Base";
void print() const {
cout << name << endl;
cout << static_cast<const T&>(*this).name << endl;
}
};
struct Derived1 : public Base<Derived1> {
string name = "Derived1";
};
struct Derived2 { // こいつを弾く仕組みが欲しい
string name = "Derived2";
};
// 関数テンプレートは部分特殊化できないためこんぱいるえらー
template <class T, bool b = is_base_of<Base<T>, T>::value>
ostream& operator << (ostream& os, const Base<T>& base) {
static_assert(b, "T is not derived from Base<T>");
}
template <class T>
ostream& operator << <T, true> (ostream& os, const Base<T>& base) {
base.print();
return os;
}
int main(){
// Derived1 d1;
// Derived2 d2;
// f(d1);
// f(d2);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTxjbGFzcyBUPgpzdHJ1Y3QgQmFzZSB7CiAgICBzdHJpbmcgbmFtZSA9ICJCYXNlIjsKICAgIHZvaWQgcHJpbnQoKSBjb25zdCB7CiAgICAgICAgY291dCA8PCBuYW1lIDw8IGVuZGw7CiAgICAgICAgY291dCA8PCBzdGF0aWNfY2FzdDxjb25zdCBUJj4oKnRoaXMpLm5hbWUgPDwgZW5kbDsKICAgIH0KfTsKCnN0cnVjdCBEZXJpdmVkMSA6IHB1YmxpYyBCYXNlPERlcml2ZWQxPiB7CiAgICBzdHJpbmcgbmFtZSA9ICJEZXJpdmVkMSI7Cn07CgpzdHJ1Y3QgRGVyaXZlZDIgeyAvLyDjgZPjgYTjgaTjgpLlvL7jgY/ku5XntYTjgb/jgYzmrLLjgZfjgYQKICAgIHN0cmluZyBuYW1lID0gIkRlcml2ZWQyIjsKfTsKCi8vIOmWouaVsOODhuODs+ODl+ODrOODvOODiOOBr+mDqOWIhueJueauiuWMluOBp+OBjeOBquOBhOOBn+OCgeOBk+OCk+OBseOBhOOCi+OBiOOCieODvAp0ZW1wbGF0ZSA8Y2xhc3MgVCwgYm9vbCBiID0gaXNfYmFzZV9vZjxCYXNlPFQ+LCBUPjo6dmFsdWU+Cm9zdHJlYW0mIG9wZXJhdG9yIDw8IChvc3RyZWFtJiBvcywgY29uc3QgQmFzZTxUPiYgYmFzZSkgewogICAgc3RhdGljX2Fzc2VydChiLCAiVCBpcyBub3QgZGVyaXZlZCBmcm9tIEJhc2U8VD4iKTsKfQoKdGVtcGxhdGUgPGNsYXNzIFQ+Cm9zdHJlYW0mIG9wZXJhdG9yIDw8IDxULCB0cnVlPiAob3N0cmVhbSYgb3MsIGNvbnN0IEJhc2U8VD4mIGJhc2UpIHsKICAgIGJhc2UucHJpbnQoKTsKICAgIHJldHVybiBvczsKfQoKaW50IG1haW4oKXsKICAgIC8vIERlcml2ZWQxIGQxOwogICAgLy8gRGVyaXZlZDIgZDI7CiAgICAvLyBmKGQxKTsKICAgIC8vIGYoZDIpOwogICAgcmV0dXJuIDA7Cn0K
prog.cpp:29:65: error: non-class, non-variable partial specialization 'operator<< <T, true>' is not allowed
ostream& operator << <T, true> (ostream& os, const Base<T>& base) {
^