将const char * 转换为const std::string &

8

我认为以下代码应该会产生一个错误:

#include <iostream>
#include <string>

static void pr(const std::string &aStr)
{
    std::cout << aStr << "\n";
}

int main(void)
{
    const char *a = "Hellu";

    pr(a);

    return 0;
}

但是gcc 4.1.2成功编译了它。

是不是std::string的构造函数在干扰,创建了一个std::string实例?

我认为不应该这样,因为引用只是变量的别名(在这种情况下,引用所指向的std::string类型的变量不存在)。

有人能解释一下为什么代码能够成功编译吗?

提前致谢。

2个回答

13

是的,如果给定一个对常量的引用,编译器可以/将会合成一个临时对象(在本例中为std::string类型)并将该引用绑定到该临时对象。

然而,如果引用不是指向常量对象,那么这种方法就行不通了——只有对常量的引用才能像这样绑定到一个临时对象(尽管至少广泛使用的编译器允许非const引用绑定到引用上)。


有趣的事实。人们每天都在学习;)。不过我没有理解你的第二句话。您是否意味着如果函数头是void pr(std::string &aStr),则无法按照标准暗示构建临时对象? - Sebastian Hoffmann
@JerryCoffin,那么有没有办法阻止编译器生成临时实例? - Young-hwi
@orchistro,只是好奇:你为什么想要防止隐式转换? - Frederick Roth
我只想让编译器生成一个错误,但似乎没有办法做到这一点(在gcc的情况下),我只能忍受它。 - Young-hwi
1
@orchistro:在我看来,显而易见的答案是暂时修改函数以接受非const的std::string引用,这样编译器就会拒绝任何试图传递char *char const *的东西。我可能会使用typedef使切换参数类型相对快速和容易。 - Jerry Coffin
显示剩余6条评论

3
您遇到的是隐式转换。
下面是来自C++标准(SC22-N-4411.pdf)的一则引用: “1.类对象的类型转换可以通过构造函数和转换函数指定。这些转换称为用户定义转换,用于隐式类型转换(第4条),初始化(8.5)和显式类型转换(5.4、5.2.9)。”
因此,编译器只是按预期工作,并调用了您提到的std::string构造函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接