我试图创建一个is_foo
函数,然后可以将其与enable_if
一起使用,以确定某个类型是否从某个CRTP基类派生。下面的代码是我尝试实现is_foo
函数的尝试,但实际上并不起作用。有人可以告诉我我需要更改以解决此问题吗?
谢谢。
#include <iostream>
#include <type_traits>
#include <functional>
using namespace std;
template <class Underlying, class Extra>
struct Foo
{
int foo() const { return static_cast<const Underlying*>(this)->foo(); }
};
template<class T>
struct Bar : Foo<Bar<T>, T>
{
int foo() const { return 42; }
};
template<class T>
struct is_foo { static const bool value = false; };
template<class Underlying, class Extra>
struct is_foo<Foo<Underlying, Extra> > { static const bool value = true; };
template<class T>
void test(const T &t)
{
cout << boolalpha << is_foo<T>::value << endl;
}
int main()
{
Bar<int> b;
test(b);
}
最佳答案
在Foo基础中添加一个typedef:
template < typename Derived >
struct crtp
{
...
typedef int is_crtp;
};
实现has_field检查:
BOOST_MPL_HAS_XXX(is_crtp)
实现您的元功能:
template < typename T >
struct is_crtp_derived : has_is_crtp<T> {};
这是我能想到的唯一能够正确捕获孙子孙女的方法。不过,它容易产生误报,因此您需要选择过于讨厌的名称,以免在其他地方意外使用。您的另一个选择是根据is_base_of实现您的元功能:
template < typename T >
struct is_crtp_derived : std::is_base_of< crtp<T>, T> {};
这当然不会抓到孙子。