我有一个编译的代码,它看起来像:
void test1(const std::string &name)................
test1("myName");
但是,如果我从声明中删除const
:
void test2(std::string &name)................
test2("myName");
代码没有编译。
为什么const std::string
会编译?据我所知,将调用相同的隐式构造函数,将char *
转换为std::string
。
我正在使用Visual Studio 2013,以防这可能与答案有关。
答案 0 :(得分:5)
当隐式转换发生时,你得到一个临时 std::string
(从技术上讲,重要的是它是一个xvalue)。您不能将临时值绑定到左值引用std::string &
,但可以绑定到左值引用const std::string &
或右值引用std::string &&
。
同样的事情发生在这里:
const int &x = 5;
int &x = 5; // error
答案 1 :(得分:2)
在第二种情况下出现错误,因为临时无法绑定到非const引用。
test("myName");
尝试在第二种情况下将临时构造对象绑定到左值,因此出错
答案 2 :(得分:2)
"myName"
是一个c风格的字符串,其类型为const char[]
。由于它不是std::string
,因此需要将其转换为一个。发生这种情况时,会创建一个临时string
。该临时字符串不能绑定到引用,但它可以绑定到const
引用,因为它会将其生命周期延长到表达式的末尾。
您还可以通过string
之类的右值引用传递void foo(std::string && bar)
。这会将临时string
移动到函数中并为您提供相同的效果。
第三种选择是通过值string
传递void foo(std::string bar)
。这适用于临时工和非临时工,并会根据字符串的来源进行复制或移动。
答案 3 :(得分:0)
问题在于您使用的&
作为参考。使用字符串文字调用函数时,无法传递非const引用。