简体   繁体   English

为什么某些类型不能使用统一的初始化语法?

[英]Why some types does not work with uniform initialization syntax?

While updating some of my C++98 code to C++11, I noticed uniform initialization is not so uniform. 在将我的一些C ++ 98代码更新为C ++ 11时,我注意到统一的初始化不是那么统一。 Some of them related to incomplete type like void , while other are related to pod. 其中一些与不完整类型(例如void ,而其他一些与pod相关。 eg For trivially copyable types, uniform initialization is not working for both direct initialization or copy initialization, when initialization involves copy/move constructor. 例如,对于琐碎的可复制类型,当初始化涉及复制/移动构造函数时,统一初始化对直接初始化或复制初始化均无效。

eg 例如

template<class T>
T foo() { return T("Hello World");}
foo<void>();
foo<std::string>();
--------
template<class T>
T foo() { return T{"Hello World"};}
foo<void>();
foo<std::string>();

While the first part compiles, the second half fails with error: compound literal of non-object type 'void' 在第一部分编译时,第二部分失败并error: compound literal of non-object type 'void'

struct pod { int x;int y;};
pod p{1,2}; //ok pod p(1,2) is error as usual
pod p2(p);

struct foo
{
    foo(foo const& rhs) : p_(rhs.p_){}
    pod p_;
};
--------
struct pod { int x;int y;};
pod p{1,2}; 
pod p2{p};

struct foo
{
    foo(foo const& rhs) : p_{rhs.p_}{}
    pod p_;
};

Here also, the second half fails on copy construction with error: cannot convert 'pod' to 'int' in initialization . 同样在这里,后半部分在复制构造上失败并error: cannot convert 'pod' to 'int' in initialization Though I think, this pod class is a trivial type (or even can be trivially copyable type) in c++11, but the problem remains same except primitive types 尽管我认为,此pod类是c ++ 11中的普通类型(甚至可以是普通复制类型),但是除了原始类型之外 ,问题仍然相同

NOTE: 注意:

while the following works, 尽管以下工作有效,

struct conv
{
    operator int()const { return 1;}
};
pod p{1,2};
pod p2{conv{}};

This does not, 这不是

struct conv
{
    operator pod()const { return pod{1,2};}
};
pod p{1,2};
pod p2{conv{}};

I also noticed C array does work with uniform initialization, but not with copy/move constructor. 我还注意到C数组确实适用于统一初始化,但不适用于复制/移动构造函数。 But that may be due to array being an aggregate which does not have copy/move constructor or assignment. 但这可能是由于数组是一个没有复制/移动构造函数或赋值的聚合。 Though I do not know why in c++11 those syntax are not allowed(specifically when they are class member, implicit copy/move does exactly that). 虽然我不知道为什么在c ++ 11中不允许使用这些语法(特别是当它们是类成员时,隐式复制/移动确实可以做到这一点)。

So, why can't I blindly change all C++98 initialization to C++11 style uniform initialization (Well , except for the types which has initializer list ! ) ? 那么,为什么我不能盲目地将所有C ++ 98初始化更改为C ++ 11样式统一初始化(好,除了具有初始化列表的类型!)?

I am using GCC 4.8.1 我正在使用GCC 4.8.1

"Uniform initialization" is a non-standard term which was used somewhat unfortunately in promotion of the initializer-list feature during its proposal phase. “统一初始化”是一个非标准术语,不幸的是,在提议阶段,该术语在促进初始化列表功能时使用。

No, you can't use it everywhere. 不,您不能在任何地方使用它。 In my experience, it's best to restrict it to 以我的经验,最好将其限制为

  • aggregates (with no constructor; C++98 already allowed this but C++11 extends support) 聚合(没有构造函数; C ++ 98已允许这样做,但C ++ 11扩展了支持)
  • sequences ( initializer_list ) 序列( initializer_list
  • return by value expressions calling a non-explicit constructor 通过值表达式return调用非显式构造函数

Blindly changing everything and expecting no semantic change is just argumentum ad novitatem — doing something because it's new and different, not because it's appropriate. 盲目地改变一切并且不期望语义上的改变只是争论的论据–做某事是因为它是新的和与众不同的,而不是因为它是适当的。

As for generic programming, yes it's hard to correctly support situations spanning the above categories. 对于泛型编程,是的,很难正确地支持上述类别的情况。 Post specific complaints to the message board at http://isocpp.org and perhaps the guys in charge of the language will work harder to restore the generic order which "uniform initialization" was supposed to improve, not aggravate :v) . 将特定的投诉发布到http://isocpp.org上的留言板,也许负责该语言的人将更加努力地恢复“统一初始化”应该改善的通用顺序,而不是加重:v)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM