如何存在成员?

时间:2011-09-14 23:28:38

标签: c++ templates metaprogramming

编辑:对不起,这个问题是重复的。原文:SFINAE to check for inherited member functions

我有一个模板化的函数(在用于测试的类中):

template <class CHandler>
void InitHandler(CHandler &handler)
{
    handler.setId(0);
    handler.SetCache(m_pCache.get());
    handler.m_pScience = m_pScience;
}

但是,可能会使用没有m_pScience成员的模板参数调用此函数。

我是否可以使用模板元编程来设置此成员(如果存在)?

2 个答案:

答案 0 :(得分:5)

重新想象这个答案:How to detect whether there is a specific member variable in class?

template<typename T> struct Hasm_pScience 
{ 
    struct Fallback { int m_pScience; }; // introduce member name "m_pScience"
    struct Derived : T, Fallback { };

    template<typename C, C> struct ChT; 

    template<typename C> static char (&f(ChT<int Fallback::*, &C::m_pScience>*))[1]; 
    template<typename C> static char (&f(...))[2]; 

    static bool const value = sizeof(f<Derived>(0)) == 2;
}; 

struct A { float m_pScience; };
struct B { int X; };

int main(int argc, _TCHAR* argv[])
{
    std::cout << Hasm_pScience<A>::value << std::endl; // 1
    std::cout << Hasm_pScience<B>::value << std::endl; // 0

    return 0;
}

谷歌的一般原则是SFINAE(替换失败不是错误)。

答案 1 :(得分:1)

通常,当您需要模板中的某个成员时,您应该强制模板的用户实现它,即使它没有任何用途。常见示例是stl setmap,您需要在其中定义operator <

有许多(正确的)方法可以做你想要的,但它们都涉及你要求模板的用户拥有某个成员变量或功能。

你也可以有两个模板,一个用于m_pScience的模板,另一个用于没有模板的模板,但我不建议这样做。这样,您必须确保两个模板之间的代码始终保持一致。