我不知道这是编译器错误(Arch Linux 上的 gcc 4.8)还是标准的问题,但下面的代码无法编译。为什么允许 getFoo1 而不允许 getFoo2?
struct Foo {
int _i;
Foo(int i):_i(i) { }
};
Foo getFoo1(int i) {
if(i == 3) {
return { i + 2 };
} else {
return { i };
}
}
Foo getFoo2(int i) {
return i == 3 ? { i + 2 } : { i };
}
int main() {
auto foo1 = getFoo1(3); //fine
auto foo2 = getFoo2(3); //oops
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我刚刚被这种看似无辜的尝试所捕获,它使用统一的初始化语法来调用带有大小和字符值的std::string构造函数:
std::string s{ 10, '\0' };
Run Code Online (Sandbox Code Playgroud)
我认为这将创建一个长度为10的字符串,用\0.初始化.
虽然它实际上调用构造函数来获取初始化列表,因此创建一个长度为2的字符串,用{'\n', '\0'}!初始化!
请参阅Coliru的演示.
有没有办法在使用统一初始化时避免这个陷阱?或者我必须要小心?
注意: 之前已经提出过类似的问题,但没有回答如何避免这个陷阱.
假设我有这个结构:
struct MyStruct {
int field1;
char *field2;
MyStruct(int a, char* b): field2(b) {
field1 = doStuff(a);
}
MyStruct(int a): MyStruct(a, nullptr) {}
~MyStruct();
}
Run Code Online (Sandbox Code Playgroud)
据我所知,这不是一个聚合,因为我有一些构造函数.
我想要实现的是以自定义方式使用花括号初始化程序,这意味着使用如下代码:
MyStruct x = { 1, "string" };
Run Code Online (Sandbox Code Playgroud)
它隐式调用正确的构造函数(在本例中是第一个).
这有可能吗?
我可以看到std :: string只有一个CTOR initializer_list:string (initializer_list<char> il);所以初始化列表应该与chars一起使用,对吧?为什么std::string{"some_str"}有效,它得到了const char*,对吧?
c++ stdstring initialization-list uniform-initialization c++11
给出以下代码:
#include <functional>
#include <string>
#include <iostream>
class test
{
public:
struct info
{
std::string name {""};
std::function<bool()> func;
};
//info my_info { "test_name", [&]{return member_func();} }; // <------ ERROR HERE
std::pair<std::string, std::function<bool()>> my_info_pair { "test_name", [&]{return member_func();} };
bool member_func()
{
std::cout << "member_func\n";
return true;
};
};
int main() {
std::cout << "start\n";
test t;
std::cout << t.my_info_pair.first << std::endl;
t.my_info_pair.second();
std::cout << "end\n";
}
Run Code Online (Sandbox Code Playgroud)
此代码有效。但是,如果我取消注释行的注释-它试图以info与std :: pair 初始化相同的方式初始化结构,则它将失败。我不知道为什么...
错误得到的是:
prog.cc:15:60: error: could not convert '{"test_name", …Run Code Online (Sandbox Code Playgroud)