Joh*_*itb 24 c++ initializer-list c++11
我最近遇到了初始化列表的一些问题.考虑一个存储类似地图数据的程序
struct MyMapLike {
MyMapLike(std::map<std::string, int> data)
:data(std::move(data))
{ }
private:
std::map<std::string, int> data;
};
Run Code Online (Sandbox Code Playgroud)
这看起来很直接.但是在初始化时,它会变得难看.我想让它看起来像
MyMapLike maps = { { "One", 1 }, { "Two", 2 } };
Run Code Online (Sandbox Code Playgroud)
但是编译器并不想接受这一点,因为上面意味着它应该寻找一个两个参数的构造函数,可以接受{ "One", 1 }和{ "Two", 2 }分别.我需要添加额外的大括号,使它看起来像一个单参数构造函数接受{ { ... }, { ... } }
MyMapLike maps = { { { "One", 1 }, { "Two", 2 } } };
Run Code Online (Sandbox Code Playgroud)
我不想那样写.由于我有类似map的类,并且初始化程序具有映射列表的抽象值,因此我想使用前一版本,并且独立于任何此类实现细节,例如构造函数的嵌套级别.
一个解决方法是声明一个初始化列表构造函数
struct MyMapLike {
MyMapLike(std::initializer_list<
std::map<std::string, int>::value_type
> vals)
:data(vals.begin(), vals.end())
{ }
MyMapLike(std::map<std::string, int> data)
:data(std::move(data))
{ }
private:
std::map<std::string, int> data;
};
Run Code Online (Sandbox Code Playgroud)
现在我可以使用前者,因为当我有一个初始化列表构造函数时,整个初始化列表被视为一个元素而不是被分割成元素.但我认为构造函数的这种单独需求是死的.
我正在寻找指导:
如果您同意我之前的初始化方式更好,您能想到什么解决方案?
GMa*_*ckG 10
由于我有类似地图的类,并且初始化程序具有映射列表的抽象值,我想使用以前的版本
而herin就是问题所在:由你来提供构造函数,让你的类被视为地图.你把你的解决方案称为解决方案,但是没有什么可以解决的.:)
但我认为构造函数的这种单独需求是死的.
它是,但不幸的是,因为它是你的类,你必须指定初始化程序列表的工作方式.
您如何看待前者和后者的初始化形式?在这种情况下需要额外的括号是否有意义?
我认同.我认为允许构造函数调用不仅仅是在语法与构造函数匹配时,而是在语法与构造函数的单个参数的某个构造函数匹配时,以及依此类推.
struct A { int i; };
struct B { B(A) {} B(int) {} };
struct C { C(B) {} };
C c{1};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您是否认为添加初始化列表构造函数的要求不好?
不.它可以让您获得所需的语法,但如果我们让编译器更难以使用构造函数,那么就不会产生问题.
我同意这很丑。一旦我超出了非常简单的情况,我通常会废弃初始化列表,因为它们非常有限。对于你的情况,我会选择 boost::assign ,虽然不那么简洁,但可以提供更好的灵活性和控制。
| 归档时间: |
|
| 查看次数: |
3359 次 |
| 最近记录: |