Mat*_*att 6 c++ templates template-specialization template-meta-programming
有没有专门化这样的模板,只有T有成员函数才能使专业化适用hash
?(注意这只是我想要做的一个例子.我知道对于每个具有hash
在operator==
成员函数中自己检查它的函数的类会更有意义,但我只是想知道这种类型事情是可能的.)
template <class T>
bool equals(const T &x, const T &y)
{
return x == y;
}
template <class T> // somehow check if T has a member function 'hash'
bool equals<T>(const T &x, const T &y)
{
return x.hash() == y.hash() && x == y;
}
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我更喜欢预C++ 11解决方案.
这是我自己的代码中的一个例子.正如您可能从其中一个结构名称猜测的那样,这是基于替换失败不是错误的原则.该结构has_member_setOrigin
定义了两个版本test
.如果U
没有成员,第一个就不能满足setOrigin
.由于这不是模板替换中的错误,因此它就好像它不存在一样.因此,多态函数的分辨率顺序找到test(...)
否则将具有较低优先级的分辨率顺序.在value
随后通过的返回类型确定test
.
接下来是使用模板的两个callSetOrigin
(相当于您的equals
)定义enable_if
.如果你检查enable_if
你会看到如果第一个模板参数为真,则enable_if<...>::type
定义,否则不定.这再次在其中一个定义中产生替换错误,callSetOrigin
使得只有一个存活.
template <typename V>
struct has_member_setOrigin
{
template <typename U, void (U::*)(const Location &)> struct SFINAE {};
template <typename U> static char test(SFINAE<U, &U::setOrigin>*);
template <typename U> static int test(...);
static const bool value = sizeof(test<V>(0)) == sizeof(char);
};
template<typename V>
void callSetOrigin(typename enable_if <has_member_setOrigin<V>::value, V>::type &p, const Location &loc) const
{
p.setOrigin(loc);
}
template<typename V>
void callSetOrigin(typename enable_if <!has_member_setOrigin<V>::value, V>::type &p, const Location &loc) const
{
}
Run Code Online (Sandbox Code Playgroud)
忘了我也提供了一个定义enable_if
:
#ifndef __ENABLE_IF_
#define __ENABLE_IF_
template<bool _Cond, typename _Tp>
struct enable_if
{ };
template<typename _Tp>
struct enable_if<true, _Tp>
{ typedef _Tp type; };
#endif /* __ENABLE_IF_ */
Run Code Online (Sandbox Code Playgroud)