'string'(又名'basic_string<char>')的初始化没有匹配的构造函数
no matching constructor for initialization of 'string' (aka 'basic_string<char>')
代码如下:
#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;
}
此代码使用 gcc 4.8.3 编译,但不使用 clang 3.5 编译,有人能告诉我它有什么问题吗?
我遇到这样的错误:
main.cpp:45:12: error: no matching constructor for initialization of 'string' (aka 'basic_string<char>')
string s {Foo{}};
^ ~~~~~~~
clang --version:
clang version 3.5.0 (tags/RELEASE_350/final 216961)
Target: x86_64-suse-linux
Thread model: posix
谢谢
我认为这是一个 clang 错误。根据 [dcl.init.list] 中的列表初始化规则:
List-initialization of an object or reference of type T
is defined as follows:
- If
T
is a class type and the initializer list has a single element of type cv U
, where U
is T
or a class derived from T
, [...]
- Otherwise, if
T
is a character array and [...]
- Otherwise, if
T
is an aggregate, [...]
- Otherwise, if the initializer list has no elements [...]
- Otherwise, if
T
is a specialization of std::initializer_list<E>
, [...]
- Otherwise, if
T
is a class type, constructors are considered. The applicable constructors are enumerated
and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see
below) is required to convert any of the arguments, the program is ill-formed.
- [...]
T
是class类型,所以我们考虑basic_string
constructors。该列表中的#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 抱怨有:
no known conversion from Foo
to const std::__cxx11::basic_string<char> &
for 1st argument
虽然有,所以我将其归档为 LLVM Bug 23658。
代码如下:
#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;
}
此代码使用 gcc 4.8.3 编译,但不使用 clang 3.5 编译,有人能告诉我它有什么问题吗?
我遇到这样的错误:
main.cpp:45:12: error: no matching constructor for initialization of 'string' (aka 'basic_string<char>')
string s {Foo{}};
^ ~~~~~~~
clang --version:
clang version 3.5.0 (tags/RELEASE_350/final 216961)
Target: x86_64-suse-linux
Thread model: posix
谢谢
我认为这是一个 clang 错误。根据 [dcl.init.list] 中的列表初始化规则:
List-initialization of an object or reference of type
T
is defined as follows:
- If
T
is a class type and the initializer list has a single element of type cvU
, whereU
isT
or a class derived fromT
, [...]- Otherwise, if
T
is a character array and [...]- Otherwise, if
T
is an aggregate, [...]- Otherwise, if the initializer list has no elements [...]
- Otherwise, if
T
is a specialization ofstd::initializer_list<E>
, [...]- Otherwise, if
T
is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.- [...]
T
是class类型,所以我们考虑basic_string
constructors。该列表中的#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 抱怨有:
no known conversion from
Foo
toconst std::__cxx11::basic_string<char> &
for 1st argument
虽然有,所以我将其归档为 LLVM Bug 23658。