反正是否基于C++中的参数成员专门化模板?

Mat*_*att 6 c++ templates template-specialization template-meta-programming

有没有专门化这样的模板,只有T有成员函数才能使专业化适用hash?(注意这只是我想要做的一个例子.我知道对于每个具有hashoperator==成员函数中自己检查它的函数的类会更有意义,但我只是想知道这种类型事情是可能的.)

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解决方案.

Ben*_*son 8

这是我自己的代码中的一个例子.正如您可能从其中一个结构名称猜测的那样,这是基于替换失败不是错误的原则.该结构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)

  • 这是一个很好的答案,但如果你添加一些有关它如何工作的解释会更好. (2认同)