C++ 为什么初始化引用在一个构造函数中成功,而在另一个构造函数中失败
我们的代码使用了如下内容来传递常量字符串引用:C++ 为什么初始化引用在一个构造函数中成功,而在另一个构造函数中失败,c++,string,c++11,reference,initialization,C++,String,C++11,Reference,Initialization,我们的代码使用了如下内容来传递常量字符串引用: const char* str = // passed in; const std::string& sym(str); 然后我需要将其修复为take symbol only作为前5个字符,我做到了: const std::string& sym(str, 5); 但这给我带来了一个编译错误: error: expression list treated as compound expression in initializer
const char* str = // passed in;
const std::string& sym(str);
然后我需要将其修复为take symbol only作为前5个字符,我做到了:
const std::string& sym(str, 5);
但这给我带来了一个编译错误:
error: expression list treated as compound expression in initializer [-fpermissive]
为什么我可以调用第一个构造函数,而不能调用第二个构造函数?因为语言不允许这样做 此处的
(…)
不调用std::string
的构造函数,因为变量的类型不是std::string
,而是引用。相反,T&ref(x)
只是编写T&ref=x代码>
注意,在const std::string&sym(str)中
,因为str
的类型是const char*
而不是std::string
,所以会构造一个临时std::string
,并将其绑定到引用
这使得const std::string&sym(str)代码>主要相当于const std::string sym(str)代码>(但稍微有点混乱)。检查文档以了解引用的初始化:
对类型“cv1T1
”的引用由类型为“cv2T2
”的表达式初始化,如下所示
就你而言
const std::string& sym(str, 5);
该表达式是一个复合表达式str,5
。基本上,就像你写的一样
const std::string& sym = (str, 5);
这两种情况都归结为
const std::string& sym = 5;
或
我的理解是,该标准只允许通过单个表达式初始化引用,而不允许通过逗号分隔的一对表达式初始化引用
而且,没有匹配的构造函数(这表示Godbolt演示中的第二个错误)
作为解决方案,您可以编写:
const std::string& sym{str, 5};
根据:
如果初始值设定项是(非圆括号)带括号的初始列表或=
带括号的初始列表,则对象或引用将被列表初始化
1.应该是const std::string
和const char*
?在任何情况下,如果您想要前5个字符,您应该使用sym(str,0,5)
。如果您确定str有5个字符,那就是。是的,我的意思是const char*
,但它是用于字符串引用的。请参阅,因为引用的参数应该存在。我认为,您正在创建临时和引用。第一个案例创建临时,为什么成功?“基本上,这与您编写的const std::string&sym=(str,5);
”是一样的。GCC和Clang都拒绝std::字符串a;常数std::字符串和符号(a,a)代码>。为什么第一次初始化成功?@fluer,因为引用只能由(单个)表达式初始化。但不能用逗号分隔的一对表达式初始化。至少,这是我对标准的理解。@HolyBlackCat对了,我相信标准只允许用一个(单个)表达式初始化引用,而不允许用逗号分隔的一对表达式初始化引用。注意conststd::string&sym((a,a))代码>工作,但常量std::string&sym((a,4))代码>没有。
const std::string& sym{str, 5};