C++ 没有匹配的构造函数用于初始化';字符串';(aka';基本字符串<;char>;';)
代码如下:C++ 没有匹配的构造函数用于初始化';字符串';(aka';基本字符串<;char>;';),c++,string,c++11,clang,C++,String,C++11,Clang,代码如下: #include <iostream> #include <string> using namespace std; class Foo { public: operator string() const { return n; } string n {"foo"}; }; int main (int argc, char** argv) { string s {Foo{}}; cout << s <
#include <iostream>
#include <string>
using namespace std;
class Foo {
public:
operator string() const { return n; }
string n {"foo"};
};
int main (int argc, char** argv) {
string s {Foo{}};
cout << s << endl;
return 0;
}
谢谢我相信这是一个叮当作响的错误。根据[dcl.init.list]中的列表初始化规则:
T
类型的对象或引用的列表初始化定义如下:
- 如果
是类类型,且初始值设定项列表有一个cvT
类型的单个元素,其中U
是U
或从T
派生的类,[…]T
- 否则,如果
是字符数组并且[…]T
- 否则,如果
是聚合,[…]T
- 否则,如果初始值设定项列表没有元素[…]
- 否则,如果
是T
的专门化,[…]std::initializer\u list
- 否则,如果
是类类型,则将考虑构造函数。列举了适用的构造函数 通过过载分辨率(13.3、13.3.1.7)选择最佳的一个。如果是缩小转换(请参见 如果需要转换任何参数,则程序格式不正确T
- [……]
<代码> t>代码>是一个类类型,所以我们考虑。7在该列表中(副本构造函数)是一个适用的、可行的构造函数,因此应该选择它。在这一点上,这些表达式应该是等效的:
struct Foo {
operator std::string() const { return "hello"; }
};
std::string s{Foo{}}; // error
std::string s(Foo{}); // OK
std::string s = Foo{}; // OK
但出于某种原因,在列表初始化案例中,clang抱怨存在:
没有已知的从Foo
转换为const std::\uu cx11::basic\u string&
用于第一个参数
但是有,所以我把它归档为。一个明显的可能性:您没有包含
(而gcc恰好包含了您包含的其他标题中的
)。如果我们能够获得完整的文件(包含和全部),那就太好了缩小解释数据时人为错误的可能性。我也这样做了。我还没有看到您的编辑。转换运算符的const
限定符是否使其不适用于临时创建的对象?@bolov Nope。这是一个const
限定符,而不是&
限定符。OP中的程序使用主干的clang++3.7尖端编译,libc++I注意到使用ToT成功编译,并将#23658作为#23657的副本关闭。
clang version 3.5.0 (tags/RELEASE_350/final 216961)
Target: x86_64-suse-linux
Thread model: posix
struct Foo {
operator std::string() const { return "hello"; }
};
std::string s{Foo{}}; // error
std::string s(Foo{}); // OK
std::string s = Foo{}; // OK