模板参数包引发错误,而显式参数不是
Template parameter pack provokes error while explicit parameters not
以下代码(实时演示)在clang/gcc上运行良好,但在icc和msvc上编译失败。
唯一的区别是在class A
中使用了模板参数包,而class B
明确地给出了所有模板参数。
正确的行为是什么?代码不正确吗?我是不是错过了什么?还是仅仅因为msvc/icc不符合标准?
更新
测试的编译器版本:
作品:
- gcc 4.7.3、4.8.1、4.8.2、4.9.0、4.9.2
- clang 3.3、3.4.13.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;
}
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>
^
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.0VCINCLUDEunordered_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>'
我认为这与你对A
的部分专业化是错误的有关。编译器无法推导出专用Container
的实际模板参数。
看起来你想做一些特别的事情(毕竟这是一种专业化),以防有人用std::unordered_map
作为容器类型实例化A
。我用以下代码在你的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;
}
我在使用ICC 19.0.1时遇到了类似的问题,但使用了C++17 auto
模板参数。
解决方案是从值中分离类型并分别推导:
void f(int, int);
//bugged
template<auto F>
struct BindFunc;
template<typename... Args, void(*X)(Args...)> //warning #885: template parameter "Args" is not used in or cannot be deduced from the template argument list of class template "BindFunc<X>"
struct BindFunc<X>
{
};
//correct
template<typename T, T X>
struct BindFunc2Impl;
template<typename... Args, void(*X)(Args...)>
struct BindFunc2Impl<void(*)(Args...), X>
{
};
template<auto F>
struct BindFunc2 : BindFunc2Impl<decltype(F), F>
{
};
//BindFunc<&f> a1; //error
BindFunc2<&f> a2;
https://gcc.godbolt.org/z/gTWzm5
相关文章:
- 如何反转整数参数包
- 如何将enable-if与模板参数和参数包一起使用
- 模板元编程:如何将参数包组合成新的参数包
- C ++:在构造函数中使用参数包?
- 如何使我的 sizeof sum 结构与空参数包一起工作
- 双模板参数包
- 参数包构造函数在类模板中隐藏用户定义的转换
- 嵌套参数包扩展失败
- 参数包中的筛选器类型
- 参数和参数包的类型推导
- 为模板参数包添加别名
- enable_if中参数包的大小问题
- 如何使特征接受参数包?
- 参数包内 noexcept 说明符
- 获取可变参数模板参数包的相关类型
- 模板参数包指针的大小
- 显式指定的模板参数包
- 实例化模板时,我是否必须显式显示参数包中的类型?
- 通过跳过可选参数来填充参数包
- 模板参数包引发错误,而显式参数不是