如何解决 GCC 错误消息 «default argument for parameter of type ... has type ...»

问题:

你遇到以下形式的 GCC 错误消息

gcc_error.txt
error: default argument for parameter of type <some type> has type <some other type>

错误来源:

在你的代码中某处有一个带默认参数的函数,如下所示:

example_issue.cpp
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 关键字声明的构造函数需要在默认参数中显式调用(另见下面的特殊情况)。

在某些情况下,此错误也可能由引用像值一样初始化引起。如果上面的解决方案不能解决问题,尝试从参数类型中移除 &

特殊情况

我曾遇到这个奇怪的错误消息:

gcc_special_case_error.txt
error: default argument for parameter of type `std::string& {aka std::basic_string<char>&}' has type `const char [1]'

它由这样的模板函数引起:

template_issue.cpp
template<typename T> void doSomething(std::string arg = "") {/*...*/}

事实证明 gcc 无法正确解释它("" 应该初始化空字符串 - 显然如果不是模板函数就可以工作)。

将声明替换为

template_fix_empty.cpp
template<typename T> void doSomething(std::string arg = std::string()) {/*...*/}

有效。如果你不想用空字符串作为默认值,你可以使用这样的声明(使用显式构造函数调用)

template_fix_with_value.cpp
template<typename T> void doSomething(std::string arg = std::string("abc")) {/*...*/}

如果你想使用显式构造函数(= 使用 explicit 关键字声明的构造函数),你也需要使用这样的构造。


Check out similar posts by category: C/C++, GCC Errors