可能重复:
how to initialize function arguments that are classes with default value
#include <string>
void foo1(const std::string& s = std::string());
void foo2(std::string& s = std::string());
void foo3(const std::string s = std::string());
void foo4(std::string s = std::string());
error at foo2(): default argument for ‘std::string& s’ has type ‘std::string {aka std::basic_string<char>}’
我理解编译器的观点,但我不知道这也不适用于foo1()
。
答案 0 :(得分:23)
你不能将非const引用带到像foo2那样的临时引用。
请注意,这不是特定的默认参数。函数变量会出现相同的错误:http://ideone.com/g7Tf7L
#include <string>
using std::string;
#include <iostream>
using std::cout; using std::endl;
int main()
{
string s1 = string("s1"); // OK, copy it
const string& s2 = string("s2"); // OK, const reference to it
string& s3 = string("s3"); // ERROR! non-const reference not allowed!
cout
<< s1 << ", "
<< s2 << ", "
<< s3 << endl;
return 0;
}
当你对一个临时的const引用时,临时的生命周期被扩展到引用的生命周期(§12.2,引自我的C ++ 11 draft n3337的副本):
有两种情况下,临时表在不同于完整表达结束时被摧毁。
...
第二个上下文是引用绑定到临时的。引用绑定的临时值或作为绑定引用的子对象的完整对象的临时值在引用的生命周期内持续存在,除了:
- 构造函数的ctor-initializer(12.6.2)中的引用成员的临时绑定将持续存在,直到构造函数退出。
- 函数调用(5.2.2)中的引用参数的临时绑定将持续到包含该调用的完整表达式完成为止。
- 不扩展函数返回语句(6.6.3)中返回值的临时绑定的生存期;临时在return语句中的full-expression结束时被销毁。
- 新的初始化程序(5.3.4)中对引用的临时绑定一直持续到包含new-initializer的完整表达式完成为止。
答案 1 :(得分:3)
您可能会感到惊讶,但可以将临时表达式的值绑定到常量引用,并且表达式的生命周期延长到参考文献。但是你不能用非常量(左值)引用来做到这一点。
答案 2 :(得分:0)
foo3
和foo4
的声明是合法的,因为这些函数的参数不是参考。
foo2
的声明是非法的,因为你不能将非const引用绑定到临时引用。
为什么foo1
的声明合法?这是非常重要的const
限定符,使得此声明合法化。