模板参数包会引发错误,而显式参数则不会

Mar*_*dej 5 c++ templates variadic-templates c++11

以下代码(现场演示)在 clang/gcc 上运行良好,但在 icc 和 msvc 上编译失败。

唯一的区别是在 中使用模板参数包class A,而class B显式给出所有模板参数。

什么是正确的行为?代码是否错误?我错过了什么吗?或者只是因为 msvc/icc 不符合标准?

更新

测试的编译器版本:

作品:

  • 海湾合作委员会 4.7.3、4.8.1、4.8.2、4.9.0、4.9.2
  • 铿锵 3.3、3.4.1、3.5.0、3.5.1、3.6.0rc2

不起作用:

  • msvc-12.0 (2013) 更新 4
  • icc-13.0.1

代码

#include <unordered_map>

template <class Container>
struct A
{};

// the following won't compile on some compilers (msvc, icc)
template <class... Args>              // line 8
struct A<std::unordered_map<Args...>> // line 9
{
};

template <class Container>
struct B
{};

// the following compiles fine
template <class K, class T, class H, class P, class A>
struct B<std::unordered_map<K, T, H, P, A>>
{
};

int main(void)
{
    typedef std::unordered_map<int, int> my_map;
    A<my_map> a;
    B<my_map> b;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

ICC 错误

test-parameter-pack.cpp(9): error: too few arguments for class template "std::unordered_map"

struct A<std::unordered_map<Args...>>
^

test-parameter-pack.cpp(8): warning #885: template parameter "Args" is not used in or cannot be deduced from the template argument list of class template "A<<error-type>>"

template <class... Args>
^
Run Code Online (Sandbox Code Playgroud)

msvc-12.0 更新 4 时出错

test-parameter-pack.cpp
test-parameter-pack.cpp(9) : error C2976: 'std::unordered_map' : too few template arguments
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\unordered_map(79) : see declaration of 'std::unordered_map'
test-parameter-pack.cpp(10) : error C3203: 'unordered_map' : unspecialized class template can't be used as a template argument for template parameter 'Container', expected a real type
test-parameter-pack.cpp(8) : error C3211: 'A<int>' : explicit specialization is using partial specialization syntax, use template <> instead
test-parameter-pack.cpp(10) : see declaration of 'A<int>'
Run Code Online (Sandbox Code Playgroud)

haa*_*vee 2

我认为这与您的部分专业化是错误的事实有关A。编译器无法推断出专门的Container.

看起来您想做一些特殊的事情(毕竟这是一种专业化),以防有人实例A化为std::unordered_map容器类型。我使用以下代码在 icc 上编译了您的现场演示。

请注意,Container现在是一个模板模板参数,它本身采用任意数量的模板参数。这允许检测实际使用中的容器类型std::unordered_map的使用情况。我确实做了一些简化,以减少到最小的示例。

#include <unordered_map>

template <template <typename...> class Container, typename... Args>
struct A
{};

// the following won't compile on some compilers (msvc, icc)
template <typename... Args>
struct A<std::unordered_map, Args...>
{
};


int main(void)
{
    A<std::unordered_map, int, int> a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)