2

タグのディスパッチについては、テンプレートから渡された型を切り替えるに記載されています。

次のようなことを行うことは可能ですか (可能であればどのように):

struct Tag1 {};
struct Tag2 {};

template<class T, typename R>
R get();

template<>
double get<Tag1>() {return 1.3;}

template<>
char const *get<Tag2>() {return "hello";}

double aDouble = get<Tag1>();
char const *aString = get<Tag2>();

上記のコードにより、オーバーロードされた関数のあいまいな呼び出しについてコンパイラが文句を言うようになりますが、最後の 2 行で使用の意図が伝えられることを願っています。

どうも

4

3 に答える 3

3

std::enable_ifand std::is_same(C++11)、または同等のブーストを使用できます。

template <typename Tag>
typename std::enable_if<std::is_same<Tag, Tag1>::value, double>::type get()
{ ... }

template <typename Tag>
typename std::enable_if<std::is_same<Tag, Tag2>::value, char const *>::type get()
{ ... }
于 2012-08-20T14:17:21.287 に答える
1

テンプレート パラメーターの数が異なる関数テンプレートは互いにオーバーロードするため、特殊化を定義するのではなく、オーバーロードを定義します。このようなものが動作するはずです:

struct Tag1 {};
struct Tag2 {};

template<class T> struct MapResult;

template<> struct MapResult<Tag1> { typedef double Result; };
template<> struct MapResult<Tag2> { typedef char const* Result; };

template<class T>
typename MapResult<T>::Result get();

template<> double get<Tag1>() {return 1.2;}
template<> char const *get<Tag2>() {return "hello";}
于 2012-08-20T14:37:24.710 に答える
0

の 2 番目のテンプレート パラメーターは、戻り値の型としてのみ表示されるgetため、推測できません。たとえば、呼び出した場合、その呼び出しは正しい専門化に解決されます。get<Tag1>()get<Tag1, double>get<Tag1, int>get<Tag1, double>()

getただし、2 つのテンプレート パラメーターを持つ関数テンプレートになりたくないのではないかと思います。戻り値の型は、おそらく最初のパラメーターの関数であることを意図しています。getそのため、次のように宣言することをお勧めします。

namespace result_of {

template<typename T>
struct get;

}

template<typename T>
typename result_of::get<T>::type get();

whereresult_of::getは、期待される結果の型を計算するメタ関数になります。関数テンプレートを特殊化するのではなく、物事を簡単にするためgetに、すべての卵をresult_of::getバスケットに入れます。

namespace result_of {

template<typename T>
struct get;

}

template<typename T>
typename result_of::get<T>::type get()
{ return result_of::get<T>::apply(); }

namespace result_of {

template<>
struct get<Tag1> {
    typedef double type;

    static type apply()
    { return 1.3; }
};

template<>
struct get<Tag2> {
    typedef const char* type;

    static type apply()
    { return "hello"; }
};

}

一般に、関数テンプレートよりもクラス テンプレートを特殊化する方がはるかに一般的であり、関数テンプレートを特殊化する必要があるように見える場合は、関数テンプレートがその実装を完全にクラス テンプレートに委任できるようにすることで、より簡単になることがよくあります。

于 2012-08-20T15:23:25.817 に答える