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<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
    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<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)
}

どうすればこれを達成できますか?

4

1 に答える 1

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.
于 2012-06-12T07:50:40.203 に答える