While updating some of my C++98 code to C++11, I noticed uniform initialization is not so uniform. Some of them related to incomplete type like void, while other are related to pod. e.g. For trivially copyable types, uniform initialization is not working for both direct initialization or copy initialization, when initialization involves copy/move constructor.
e.g.
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'
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. 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
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. 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).
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 ! ) ?
I am using GCC 4.8.1