Обновляя часть своего кода C++98 до C++11, я заметил, что юниформ-инициализация не такая унифицированная. Некоторые из них связаны с неполным типом, например void
, а другие связаны с pod. например Для тривиально копируемых типов юниформ-инициализация не работает как для прямой инициализации, так и для инициализации копированием, когда инициализация включает конструктор копирования/перемещения.
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>();
В то время как первая часть компилируется, вторая половина дает сбой с 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_;
};
Здесь также вторая половина не работает при копировании с error: cannot convert 'pod' to 'int' in initialization
. Хотя я думаю, что этот класс pod
является тривиальным типом (или даже может быть тривиально копируемым типом) в С++ 11, но проблема остается той же за исключением примитивных типов
ПРИМЕЧАНИЕ:
в то время как следующие работы,
struct conv
{
operator int()const { return 1;}
};
pod p{1,2};
pod p2{conv{}};
Это не так,
struct conv
{
operator pod()const { return pod{1,2};}
};
pod p{1,2};
pod p2{conv{}};
Я также заметил, что массив C работает с юниформ-инициализацией, но не с конструктором копирования/перемещения. Но это может быть связано с тем, что массив является агрегатом, который не имеет конструктора копирования/перемещения или назначения. Хотя я не знаю, почему в С++ 11 этот синтаксис не разрешен (в частности, когда они являются членами класса, неявное копирование/перемещение делает именно это).
Итак, почему я не могу вслепую изменить всю инициализацию С++ 98 на равномерную инициализацию в стиле С++ 11 (ну, кроме типов, у которых есть список инициализаторов!)?
Я использую GCC 4.8.1.