Last active
June 21, 2017 08:14
-
-
Save Riyaaaaa/197de64db6c7bba488a7 to your computer and use it in GitHub Desktop.
【C++】CRTPによる静的インターフェースクラスはライブラリ実装において不適切+解決法 ref: http://qiita.com/Riyaaaa_a/items/a9af401520f238f45b80
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<class T> | |
class Base; | |
class Derived : Base<Derived>; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<class T> | |
class Interface{ | |
public: | |
void function(){ static_cast<T&>(this)->function(); } | |
}; | |
class Derived1 : Interface<Derived1>{ | |
public: | |
void function(){ std::cout << "Derived1" << std::endl; } | |
}; | |
class Derived2 : Interface<Derived2>{ | |
public: | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main.cpp:8:9: error: static_assert failed "add is not defined" | |
static_assert(std::is_same<decltype(std::declval<T>().add(std::declval<int>(),std::declval<int>())),int>::value,"ad... | |
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
main.cpp:12:7: note: in instantiation of member function 'Interface<Derived1>::Interface' requested here | |
class Derived1 : public Interface<Derived1>{ | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Derived1 : Interface<Derived1>{ | |
public: | |
int _a; | |
Derived1(){ std::cin >> _a; } | |
int add(int a, int b){ return a + b; } | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int main(){ | |
002A12A0 push ebp | |
002A12A1 mov ebp,esp | |
002A12A3 sub esp,8 | |
002A12A6 mov eax,dword ptr ds:[002A4000h] | |
002A12AB xor eax,ebp | |
002A12AD mov dword ptr [ebp-4],eax | |
Derived1 a; | |
002A12B0 mov ecx,dword ptr ds:[2A3030h] | |
002A12B6 lea eax,[a] | |
002A12B9 push eax | |
002A12BA call dword ptr ds:[2A3038h] | |
a.add(1, 1); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <class T> inline void ignore_unused_variable_warning(T const&) {} | |
template <class T> | |
void functionRequires() | |
{ | |
void (T::*fptr)() = &T::function; | |
ignore_unused_variable_warning(fptr); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<class T> | |
class Interface{ | |
void constraint() { | |
T t; | |
t.function(); | |
} | |
typedef void (Interface<T>::* type)(); | |
template <type _Tp1> | |
struct Check { }; | |
typedef Check<& Interface<T>::constraint> _Check; | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define CLASS_REQUIRE(TT, NS, Concept) \ | |
typedef void (NS::Concept <TT>::* func##TT##Concept)(); \ | |
template <func##TT##Concept _Tp1> \ | |
struct Concept_checking_##TT##Concept { }; \ | |
typedef Concept_checking_##TT##Concept< \ | |
& NS::Concept<TT>::constraint> \ | |
Concept_checking_typedef_##TT##Concept | |
// デフォルトコンストラクタの定義を要求する制約 | |
template<class TT> | |
struct DefaultConstructible { | |
void constraint() { | |
TT a; | |
ignore_unused_variable_warning(a); | |
} | |
}; | |
template<class T> | |
class Interface { | |
CLASS_REQUIRE(T, , DefaultConstructible); | |
}; | |
class myclass : Interface <myclass> {}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Interface{ | |
public: | |
virtual void function()=0; | |
virtual ~Interface()=default; | |
}; | |
class Derived1 : Interface{ | |
public: | |
void function(){ std::cout << "Derived1" << std::endl; } | |
}; | |
class Derived2 : Interface{ | |
public: | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int main(){ | |
Derived1 a; | |
Derived2 b; | |
a.function(); | |
b.function(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main.cpp:35:15: error: variable type 'Derived22' is an abstract class | |
Derived22 b; | |
^ | |
main.cpp:20:17: note: unimplemented pure virtual method 'function' in 'Derived22' | |
virtual void function()=0; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main.cpp:6:21: error: non-const lvalue reference to type 'Derived2' cannot bind to a temporary of type 'Interface<Derived2> *' | |
void function(){ static_cast<T&>(this)->function(); } | |
^ ~~~~ | |
main.cpp:23:7: note: in instantiation of member function 'Interface<Derived2>::function' requested here | |
b.function(); | |
^ | |
main.cpp:6:42: error: member reference type 'Derived2' is not a pointer; maybe you meant to use '.'? | |
void function(){ static_cast<T&>(this)->function(); } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int main(){ | |
Derived1 a; | |
Derived2 b; | |
a.function(); | |
//b.function(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<class T> | |
class Interface{ | |
public: | |
Interface(){ | |
static_assert(std::is_same<decltype(std::declval<T>().function()),void>::value,"function is not defined"); | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static_assert(std::is_same<decltype(std::is_same<std::declval<T>().関数名(std::declval<引数1>(), | |
..., | |
std::declval<引数n>()), | |
返り値の型>::value, | |
"迫真怒りのメッセージ"); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<iostream> | |
#include<utility> | |
template<class T> | |
class Interface{ | |
public: | |
Interface(){ | |
static_assert(std::is_same<decltype(std::declval<T>().add(std::declval<int>(),std::declval<int>())),int>::value,"add is not defined"); | |
} | |
}; | |
class Derived1 : Interface<Derived1>{ | |
public: | |
double add(int a,int b){return a+b;} | |
}; | |
int main(){ | |
Derived1 a; | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment