2012-06-12 57 views
0

我需要根据模板参数的某些静态成员调用具有相同参数的模板成员函数的不同版本。下面是我需要做的一种简化版本:根据模板参数调用不同版本的模板成员函数


class A { 
public: 
    //... 
    static const char fooString[]; 
}; 
const char A::fooString[] = "This is a Foo."; 

class B { 
public: 
    //... 
    static const char barString[]; 
}; 
const char B::barString[] = "This is a Bar."; 

class C { 
public: 
    //... 
    static const char fooString[]; 
}; 
const char C::fooString[] = "This is also a Foo."; 

//Many other classes which have either a fooString or a barString 

void doFoo(const char*s) { /*something*/ } 
void doBar(const char*s) { /*something else*/ } 

template&ltclass T> 
class Something { 
public: 
    //This version should be called if T has a static member called "fooString", 
    //so it should be called if T is either class A or C 
    void doSomething() { doFoo(T::fooString); } 

    //This version should be called if T has a static member called "barString", 
    //so it should be called if T is class B 
    void doSomething() { doBar(T::barString); } 
}; 


void someFunc() 
{ 
    Something&ltA> a; 
    Something&ltB> b; 
    Something&ltC> c; 

    a.doSomething(); //should call doFoo(A::fooString) 
    b.doSomething(); //should call doBar(B::barString) 
    c.doSomething(); //should call doFoo(C::fooString) 
} 

我该如何实现这一目标?

+0

你怎么能DoSomething的()定义了两次? – Jagannath

+0

这是一种伪代码。它并不实际工作,我想要发生的是,只有一个doSomethings将被使用,这取决于是否存在T :: fooString或T :: barString – Mark

回答

3

一个可能的解决方案:

#include <iostream> 
#include <type_traits> 

class A { 
public: 
    //... 
    static const char fooString[]; 
}; 
const char A::fooString[] = "This is a Foo."; 

class B { 
public: 
    //... 
    static const char barString[]; 
}; 
const char B::barString[] = "This is a Bar."; 

class C { 
public: 
    //... 
    static const char fooString[]; 
}; 
const char C::fooString[] = "This is also a Foo."; 

void doFoo(const char*s) { std::cout << "doFoo: " << s << "\n"; } 
void doBar(const char*s) { std::cout << "doBar: " << s << "\n"; } 

template<class T> 
class Something { 
public: 
    //This version should be called if T has a static member called "fooString", 
    //so it should be called if T is either class A or C 
    template <typename TT = T, typename std::enable_if<TT::fooString != 0, bool>::type = false> 
    void doSomething() { doFoo(T::fooString); } 

    //This version should be called if T has a static member called "barString", 
    //so it should be called if T is class B 
    template <typename TT = T, typename std::enable_if<TT::barString != 0, bool>::type = false> 
    void doSomething() { doBar(T::barString); } 
}; 


int main() 
{ 
    Something<A> a; 
    Something<B> b; 
    Something<C> c; 

    a.doSomething(); //should call doFoo(A::fooString) 
    b.doSomething(); //should call doBar(B::barString) 
    c.doSomething(); //should call doFoo(C::fooString) 
} 

输出:

doFoo: This is a Foo. 
doBar: This is a Bar. 
doFoo: This is also a Foo. 
+0

它不会为我编译,它说缺省模板参数只能用于类模板。但是,我从来没有听说过type_traits标题,这听起来很有希望,我会试着去研究它。 – Mark

+0

该解决方案需要一个支持C++ 11的编译器,例如gcc 4.7。 'type_traits'是新的,现在允许使用函数模板默认参数。 –

+0

谢谢,在MinGW上完美编译。 – Mark