Pull to refresh

Comments 9

В 2011 году в Стандарт добавили универсальную инициализацию (uniform initialization), которая должна навести порядок в зоопарке способов инициализации объектов, доставшемся C++ в наследство от языка C.

Напомнило вот это.
А по теме не соглашусь с рекомендацией использовать такой способ инициализации в любом новом коде. Иногда поведение таких конструкторов очень далеко от интуитивно понятного (я про конструкторы от initializer_list). Скотт Майерс в интервью Яндексу называл эту фичу одной из самых спорных.
Любопытно. А можно ссылку на это интервью?
В заключение хочется порекомендовать использовать универсальную инициализацию в любом новом коде на C++, а также явно объявлять конструкторы explicit всегда, кроме случаев, когда неявное преобразование семантически оправдано.
На мой взгляд, обе рекомендации очень категоричны. Первая из-за того, что конструкторы принимающие списки инициализации имеют очень высокий приоритет и при перегрузке можно отхватить массу неожиданностей. Второй совет я бы перефразировал с точностью до наоборот: объявлять конструкторы без explicit всегда, кроме случаев, когда преобразование явно семантически не оправдано. Иначе можно совсем лишиться синтаксического сахара и превратиться в яву. Да и стандартная библиотека делает именно так.
Действительно, многие авторитетные люди советуют использовать фигурные скобки для инициализации (uniform syntax), но нужно понимать, что подход относительно новый и нужно больше практики, что бы понять все его плюсы и минусы. Лично для меня такой синтаксис уродлив, а учитывая приоритет выбора перегрузки для списка инициализации еще и опасен. А вообще нужно понимать, что это типичный holly war.

Без объяснения, почему хороша юниформная инициализация, выглядит так, что к существующему зоопарку инициализаций добавили еще одну тварь.

Похоже uniform initialization добавил много новых зверей, а приоритет initializer list вообще убивает, неужеле нельзя было сделать его явным.
Забыли ещё упомянуть, что для explicit оператора приведения к bool не нужно делать явного преобразования при применении в if и while выражениях:

class Simple {
public:
    operator bool() const { return true; }
};

class SimpleExplicit {
public:
    explicit operator bool() const { return true; }
};

int main(int, char**) {
    
    Simple s;
    bool b = s; // OK
    
    SimpleExplicit se;
    // bool a = se; // COMPILE ERROR
    bool c = static_cast<bool>(se); // OK
    
    // BUT...
    if(se) // OK - no need explicit cast to bool
    {
    };

    return 0;
}
Sign up to leave a comment.

Articles