据我所知,均匀初始化是初始化对象的首选语法。草本萨特写入
首先,它被称为“统一初始化”,因为它是统一的--对于所有类型,包括聚合结构和数组以及std::容器.
以及对这个问题状态的公认答案
喜欢{}初始化而不是其他选项,除非您有很强的理由不这样做。
但是,请考虑以下代码:
#define BRACES
template<typename V>
class foo {
public:
template<typename W>
explicit foo(const W &w) :
#ifdef BRACES
m_v{w}
#else // #ifdef BRACES
m_v(w)
#endif // #ifdef BRACES
{}
private:
V m_v;
};
struct bar{};
int main()
{
bar b;
foo<bar>{b};
#ifdef BRACES
bar c{b};
#else // #ifdef BRACES
bar c(b);
#endif // #ifdef BRACES
} 如果#define BRACES未注释,则此代码无法使用行中的error: too many initializers for ‘bar’构建(g++ 4.8.5)
m_v{w}在foo的构造函数中。这是合理的,因为更直接的调用
bar c{b};在main中,类似的失败,它们本质上是相同的(尽管模板代码不知道这一点)。
相反,注释#define BRACES会导致构建所有内容。这是否表明要避免这种类型的模板代码中的这种形式的初始化?
编辑
@melak47 47指出,这个问题在g++5.1中没有出现,并给出了令人信服的证明。它显然在4.8.5到5.1之间消失了。
发布于 2016-03-22 19:07:01
当尝试从相同类型的对象初始化聚合时,List-初始化不太有效。
这就是CWG 1467,它的解决方案(除其他外)为[dcl.init.list]/3中的巨大列表引入了另一颗子弹来完成这项工作:
列表-对象的初始化或
T类型的引用定义如下:
T是类类型,初始化程序列表具有cv U类型的单个元素,其中U是T或从T派生的类,则从该元素初始化对象(复制列表初始化的复制初始化或直接列表初始化的直接初始化)。发布于 2016-03-22 12:02:28
当解析重载构造函数时,在考虑其他重载构造函数之前,大括号初始化将匹配使用std::initializer_list参数的构造函数。所以
bar c{b};将匹配使用std::initializer_list的构造函数,而不是生成的复制构造函数。
在第7项中讨论了这一点:在创建Scott的对象时区分()和{} --有效的现代C++。
https://stackoverflow.com/questions/36152020
复制相似问题