2012-06-12 56 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