如何解决 GCC 错误消息 «default argument for parameter of type ... has type ...»
问题:
你遇到以下形式的 GCC 错误消息
error: default argument for parameter of type <some type> has type <some other type>错误来源:
在你的代码中某处有一个带默认参数的函数,如下所示:
void doSomething(int arg1, std::set<std::string> arg2 = 15) {/*...*/}该函数的至少一个参数有默认参数(在上面的示例中,只有 arg2 有默认值),与其类型不匹配(换句话说,参数类型无法用给定的默认值初始化)。
在上面列出的示例中,如果 doSomething``() 只用一个参数调用,类型为 std::set<std::``string> 的 arg2 将被初始化为数字 15。
当然,用数字初始化 std::set<std::string``> 没有任何意义。
**注意:**大多数 STL 容器有可以用单个整数类参数调用的构造函数(用给定大小或容量初始化它们),但 std::set 没有!
识别原因
通常错误消息中的文件和行号表示导致错误的函数位置。然而,如果导致错误的函数是模板函数,通常错误消息中列出函数调用行(和相应文件)。声明模板函数的文件和行通常在错误日志中不可见,所以不要为此困惑。
此错误总是由不正确的函数声明引起,而不是由函数括号内的代码引起(C++11 lambda 函数也可能导致此错误)。
解决错误
检查函数声明中的所有默认参数。也许某个看起来可疑 - 如果没有,对每个默认参数执行以下操作:
检查函数类型是否有可以用给定类型调用的构造函数。如果没有这样的构造函数,用有效的默认参数替换它。
如果这不起作用,逐个用替代方案替换默认参数。
可能的注意事项: 使用 explicit 关键字声明的构造函数需要在默认参数中显式调用(另见下面的特殊情况)。
在某些情况下,此错误也可能由引用像值一样初始化引起。如果上面的解决方案不能解决问题,尝试从参数类型中移除 &!
特殊情况
我曾遇到这个奇怪的错误消息:
error: default argument for parameter of type `std::string& {aka std::basic_string<char>&}' has type `const char [1]'它由这样的模板函数引起:
template<typename T> void doSomething(std::string arg = "") {/*...*/}事实证明 gcc 无法正确解释它("" 应该初始化空字符串 - 显然如果不是模板函数就可以工作)。
将声明替换为
template<typename T> void doSomething(std::string arg = std::string()) {/*...*/}有效。如果你不想用空字符串作为默认值,你可以使用这样的声明(使用显式构造函数调用)
template<typename T> void doSomething(std::string arg = std::string("abc")) {/*...*/}如果你想使用显式构造函数(= 使用 explicit 关键字声明的构造函数),你也需要使用这样的构造。