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
类型的对象或引用的列表初始化定义如下:

  • 如果
    T
    是类类型,且初始值设定项列表有一个cv
    U
    类型的单个元素,其中
    U
    T
    或从
    T
    派生的类,[…]
  • 否则,如果
    T
    是字符数组并且[…]
  • 否则,如果
    T
    是聚合,[…]
  • 否则,如果初始值设定项列表没有元素[…]
  • 否则,如果
    T
    std::initializer\u list
    的专门化,[…]
  • 否则,如果
    T
    是类类型,则将考虑构造函数。列举了适用的构造函数 通过过载分辨率(13.3、13.3.1.7)选择最佳的一个。如果是缩小转换(请参见 如果需要转换任何参数,则程序格式不正确
  • [……]

<代码> 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