【发布时间】:2015-07-29 09:54:41
【问题描述】:
[temp.param] p11 说(在 N4527 中):
(...) 函数模板的模板形参包后面不应有另一个模板形参,除非该模板形参可以从函数模板的形参类型列表中推导出来或具有默认实参
在非类型模板参数包的上下文中,不能有默认参数,
那么究竟需要为包推断什么(也只是类型或值)?
即我想知道标准(C++11、14 或 1z)是否允许这样做:
template<typename T, T... A, T... B>
void foo(T) {}
第一个包的值可以明确指定,但第二个包是“无法访问”的,如果我没记错的话,它总是空的。
clang++-3.6 和 g++-5.2 似乎接受这些空的无法访问的包(甚至是非类型包),但 VC++ 14.0 拒绝它们并出现错误:
错误C3547:模板参数'B'不能使用,因为它遵循模板参数包,不能从'foo'的函数参数推导出来
【问题讨论】:
-
这些值必须是可推断的。令人惊讶的是,MSVC 是对的。看起来两者都没有实现此检查,因为两者都没有诊断出
template<class... T, class... U> void f() { },标准明确地将其标记为“错误”。 -
我希望非类型参数包存在漏洞:(
-
呃,标准需要修复:S 没有理由禁止这样做。
-
@R.MartinhoFernandes 模板参数的意义何在,您永远无法为其提供参数?
-
@T.C.如果这是基本原理,那么“或具有默认参数”也不会有例外。 (我一直使用这些类型的包;它们是 SFINAE 选择重载 IMO 的最佳方式)
标签: c++ templates c++11 language-lawyer