3

この質問は次のとおりです:テンプレート テンプレートのときに特定のオーバーロードを強制する

次のコードを検討してください。

#include <iostream>
#include <vector>
#include <array>
#include <type_traits>

// Version A
template<typename T>
void f(const T& x)
{
    std::cout<<"Version A"<<std::endl;
}

// Version B
template<typename... T1, template<typename...> class T>
void f(const T<T1...>& x)
{
    std::cout<<"Version B"<<std::endl;
}

// Version C
template<typename T1, typename TN, template<typename, TN...> class T, TN... N>
void f(const T<T1, N...>& x)
{
    std::cout<<"Version C"<<std::endl;
}

// Main
int main(int argc, char* argv[])
{
    f(double());
    f(std::vector<double>());
    f(std::array<double, 3>()); // <- How to force the use of Version C ?
    return 0;
}

デフォルトでは、生成されます (GCC 4.7.1 を使用):

Version A
Version B
Version A

Version C渡された型が適切な形状のテンプレートである場合にの使用を強制する方法(新しいバージョンの を追加fできます、std::enable_ifまたは他の C++11 型特性構文を追加できますが、可能であれば、ヘルパー クラスの追加を避けたいです) ) ?

注:このトリックは、すべての整数型 TN で機能するはずです...

4

1 に答える 1

3

テンプレート引数推定では、非型テンプレート引数の型を推定することはできません。これは、標準で明示的に述べられています。

14.8.2.5 型からのテンプレート引数の推定 [temp.deduct.type]

13 - 非型テンプレート引数の型からテンプレート型引数を推測できません。
14 - [例:

template<class T, T i> void f(double a[10][i]);
int v[10][20];
f(v); // error: argument for template-parameter T cannot be deduced

— 終了例 ]

これは機能します:

// Version C
template<typename T1, template<typename, size_t...> class T, size_t... N>
void f(const T<T1, N...>&) {
    std::cout<<"Version C"<<std::endl;
}
于 2012-12-17T10:49:51.307 に答える