Обновляя часть своего кода C ++ 98 до C ++ 11, я заметил, что равномерная инициализация не столь равномерна. Некоторые из них относятся к неполному типу, как void
в то время как другие связаны со стручком. например Для тривиально копируемых типов равномерная инициализация не работает как для прямой инициализации, так и для инициализации копирования, когда инициализация включает конструктор копирования / перемещения.
например
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
класс является тривиальным типом (или даже может быть тривиально копируемым типом) в c ++ 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 работает с равномерной инициализацией, но не с конструктором копирования / перемещения. Но это может быть связано с тем, что массив является агрегатом, который не имеет конструктора или назначения копирования / перемещения. Хотя я не знаю, почему в c ++ 11 этот синтаксис не разрешен (особенно, когда они являются членами класса, неявное копирование / перемещение делает именно это).
Итак, почему я не могу вслепую изменить всю инициализацию C ++ 98 на унифицированную инициализацию в стиле C ++ 11 (ну, кроме типов, у которых есть список инициализаторов!)?
Я использую GCC 4.8.1
«Равномерная инициализация» — это нестандартный термин, который, к сожалению, несколько использовался при продвижении функции списка инициализаторов на этапе предложения.
Нет, вы не можете использовать это везде. По моему опыту, лучше ограничить это
initializer_list
)return
по значениям выражений, вызывающих неявный конструкторСлепое изменение всего и отсутствие семантических изменений — это просто аргумент и новизна — делать что-то, потому что это новое и другое, а не потому, что это уместно.
Что касается общего программирования, да, трудно правильно поддерживать ситуации, охватывающие вышеуказанные категории. Размещать конкретные жалобы на доске объявлений на http://isocpp.org и, возможно, ребята, отвечающие за язык, будут работать усерднее, чтобы восстановить общий порядок, который «равномерная инициализация» должна была улучшить, а не усугубить: v).
Других решений пока нет …