【发布时间】:2016-06-02 16:29:42
【问题描述】:
我正在尝试编写一对重载函数,一个必须为指向非 B 或 B 的子类型的指针调用,第二个必须为指向 B 和 B 的子的指针调用. 起初我尝试对 B 使用模板的特化,但这不适用于 B 的派生类。所以我查找了 SFINAE 和 enable_if 等但无法使其工作。
泛型函数的签名是
(1)template<typename T> int f(T *t)
对于另一个我尝试像这样使用enable_if 和is_base_of:
(2)template<typename T> int f(typename enable_if<is_base_of<B, T>::value, T>::type *t)
但总是 (1) 被调用。我试图用(2)的否定来代替(1):
(1b)template<typename T> int f(typename enable_if<!is_base_of<B, T>::value, T>::type *t)
现在我得到所有 T 的错误,无论它们是否是 B 的(孩子)。
我做错了什么?解决办法是什么?
测试代码如下:
#include <type_traits>
#include <iostream>
using namespace std;
class B {};
class D : public B {};
class C {};
// (1)
/* template<typename T>
int f(T *t)
{ cout << "T\n"; } */
// (1b)
template<typename T>
int f(typename enable_if<!is_base_of<B, T>::value, T>::type *t)
{ cout << "T\n"; }
// (2)
template<typename T>
int f(typename enable_if<is_base_of<B, T>::value, T>::type *t)
{ cout << "B\n"; }
int main()
{
B b;
D d;
C c;
f(&b); // Want B; get T with (1), dont compile with (1b)
f(&d); // Want B; get T with (1), dont compile with (1b)
f(&c); // Want T; get T with (1), dont compile with (1b)
return 0;
}
【问题讨论】:
-
is_base_of<B, T>::value, T>::type不会神奇地推断出T并将其用作type。
标签: c++ templates c++11 sfinae typetraits