当模板<typename,value ... =“”> </typename,>时强制执行特定的重载

时间:2012-12-17 08:38:31

标签: c++ templates c++11 metaprogramming

这个问题如下:Force a specific overload when template template

请考虑以下代码:

#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 ...

1 个答案:

答案 0 :(得分: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;
}