Nan*_*mbe 0 c++ default-value function-templates variadic-templates explicit-instantiation
由于8.3.6 ([dcl.fct.default])/4,
在给定的函数声明中,带有默认参数的参数后面的每个参数都应具有在此或先前声明中提供的默认参数,或者应是函数参数包。
应编译以下内容:
#include <iostream>
template<typename ...Ts>
void foo(int i=8, Ts... args)
{
std::cout << "Default parameters \t= " << i << "\n";
std::cout << "Additional params \t= " << sizeof...(Ts) << "\n";
}
int main()
{
foo(); // calls foo<>(int)
foo(1, "str1", "str2"); // calls foo<const char*, const char*>(int, const char*, const char*)
foo("str3"); // ERROR: does not call foo<const char*>(int, const char*)
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但它无法编译,因为foo("str3")这让编译器感到困惑。它抱怨没有匹配的函数可供调用foo(const char*),并且无法将"str3"(type const char*) 转换为 type int。
我知道可以通过函数重载或使用命名参数习惯用法来解决这个问题(参见where to place default value parameter in variable-length function in c++?以及default arguments and variadic functions)。但是,我想知道编译器是否只是愚蠢,或者是否有真正的原因导致上面的代码示例中的预期行为未实现。换句话说,为什么即使我将函数显式实例化为 ,编译器也会抱怨foo<const char*>(int, const char*)?就好像显式实例化只是忽略默认参数的值。为什么?
具有默认值的参数仍然是位置性的。你的例子是一样的
void foo(int i=8, const char * c="hello world")
{
std::cout << "Default param \t= " << i << "\n";
std::cout << "Additional param \t= " << c << "\n";
}
int main()
{
foo(); // 8 "hello world"
foo(1, "str1"); // 1 "str1"
foo("str3"); // ERROR: parameter mismatch
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您引用的标准只是说形成是合法的
template<typename ...Ts>
void foo(int i=8, Ts... args)
Run Code Online (Sandbox Code Playgroud)
但是,当您调用它时,您仍然必须传递 anint作为第一个参数,否则在重载解析期间将不会考虑该函数。当你这样做时
foo("str3");
Run Code Online (Sandbox Code Playgroud)
编译器将查找任何foo采用 aconst char*或 a 的函数const char(&)[5],因为这是唯一的参数。这意味着您的函数完全被忽略,因为它需要int第一个参数或根本没有参数。
| 归档时间: |
|
| 查看次数: |
74 次 |
| 最近记录: |