Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么初始化引用在一个构造函数中成功,而在另一个构造函数中失败_C++_String_C++11_Reference_Initialization - Fatal编程技术网

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)(但稍微有点混乱)。

检查文档以了解引用的初始化:

对类型“cv1
T1
”的引用由类型为“cv2
T2
”的表达式初始化,如下所示

就你而言

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};