【发布时间】:2015-12-14 16:10:10
【问题描述】:
我对模板编程有点陌生,所以这可能是一个愚蠢的问题。我正在尝试使用可变参数模板来检查一个类是否有一个成员(称为member)。为此,我编写了课程
has_member。
#include <iostream>
using namespace std;
class ClassWithMember
{
public:
int member;
};
class ClassWithoutMember
{
};
template <typename T>
class has_member
{
template <typename... C>
class tester: public std::false_type
{
};
template <typename First>
class tester<First>: public std::true_type
{
void tester_fn(decltype(First::member));
};
public:
enum { value = tester<T>::value };
};
template<typename T1>
void my_function(const std::enable_if_t<has_member<T1>::value, T1> &obj)
{
cout<<"Function for classes with member"<<endl;
}
template<typename T1>
void my_function(const std::enable_if_t<!has_member<T1>::value, T1> &obj)
{
cout<<"Function for classes without member"<<endl;
}
int main()
{
ClassWithMember objWithMember;
ClassWithoutMember objWithoutMember;
my_function<ClassWithMember> (objWithMember);
my_function<ClassWithoutMember> (objWithoutMember);
}
我期待通过 SFINAE,用没有成员的类替换专用模板会静默失败并退回到通用模板。但我得到了错误:
trial.cpp: In instantiation of ‘class has_member<ClassWithoutMember>::tester<ClassWithoutMember>’:
trial.cpp:28:10: required from ‘class has_member<ClassWithoutMember>’
trial.cpp:38:41: required by substitution of ‘template<class T1> void my_function(std::enable_if_t<(! has_member<T1>::value), T1>&) [with T1 = ClassWithoutMember]’
trial.cpp:49:54: required from here
trial.cpp:24:14: error: ‘member’ is not a member of ‘ClassWithoutMember’
void tester_fn(decltype(First::member));
【问题讨论】:
-
SFINAE 仅出现在模板(或专业化)的声明中,而不是定义中。所以
tester没有启用 SFINAE。 SFINAE 很棘手,这使它保持在一个有限的位置(因此意外错误将产生错误而不是静默替换失败)并使编译器编写者稍微容易一些。 -
立即上下文中的替换失败不是大象。类模板定义不在直接上下文中。
-
嗯.. 我需要阅读 SFINAE。有没有办法使用可变参数模板来做我想做的事情?我确实有一种方法可以使用带有可变参数函数的函数重载。