我对以下问题感到困惑。我想编写一些特征结构来测试某个类是否来自另一个类。这可以通过boost :: is_base_of<>来解决。但是,我想要测试的基类有一个免费的未定义模板参数。
以下是一些代码示例:
template<typename T> class Base {};
class IntDeriv : Base<int> {};
class Foo {};
template< class TestClass >
struct is_derived_from_Base {
// how to create something that does the following and forces the compiler to deduce T
static const bool value = boost::is_base_of< Base<T> , TestClass >::value;
};
int main() {
cout << is_derived_from_Base<Foo> << endl; // should print 0
cout << is_derived_from_Base<IntDeriv> << endl; // should print 1
}
问题是如何在T
内推断Base<T>
的{{1}}。
这有可能吗?我闻到了一些enable_if,但我不确定如何把它放在一起。
答案 0 :(得分:3)
你想要什么是可能的。使用的技巧可以在C ++ 03中使用,但是你没有指定我会给你C ++ 11版本(使用decltype
,在C ++ 03中不可用):
template<class TestClass>
struct is_derived_from_Base
{
template<typename T>
static std::true_type inherited(Base<T>*);
static std::false_type inherited(void*);
static const bool value = decltype(inherited(new TestClass()))::value;
};
您可以看到live version here。
那么,它是如何运作的?
当实例化结构并且需要value
时,编译器将获得inherited(new TestClass())
的返回类型。这将调用相应的函数:如果TestClass
继承Base<T>
,则TestClass*
(由new
返回)可转换为Base<T>*
,T
正在由编译器自动推导出来。返回类型为std::true_type
。如果TestClass
未继承Base<T>
,则选择其他重载,返回类型为std::false_type
。其余的很简单:std::true_type::value = true
和std::false_type::value = false
。
还有一些极端情况:
A* a = new B();
将无法编译。 请注意,您必须按照以下方式使用它:is_derived_from_Base<Foo>::value
,而不是您编写的(is_derived_from_Base<Foo>
)。