Инициализатор внутри класса с использованием конструктора: разрешено ли это?

Недавно я нашел интересный фрагмент кода в статье Познакомьтесь с новым Формы инициализации C ++ 11 Дэнни Калев:

class C
{
string s("abc");
double d=0;
char * p {nullptr};
int y[5] {1,2,3,4};
public:
C();
};

Строка string s("abc"); мне кажется подозрительной. Я думал, что использование конструктора недопустимо, пока член инициализируется в классе. И этот код (упрощенный до class C { string s("abc");}; `) не компилируется с

  • clang 3.6.1 (аргументы компилятора: -std=c++11 -Wall -Wextra -Werror -pedantic-errors)
  • g ++ 5.1.0 (аргументы компилятора те же: -std=c++11 -Wall -Wextra -Werror -pedantic-errors )
  • vc ++ 18.00.21005.1 (аргументы компилятора: /EHsc /Wall /wd4514 /wd4710 /wd4820 /WX /Za)
  • vc ++ 19.00.22929.0 (аргументы компилятора предопределены службой: /EHsc /nologo /W4 /c)

Я прав и в этой статье есть ошибка?


person Constructor    schedule 05.06.2015    source источник


Ответы (2)


Я прав и в этой статье есть ошибка?

Да, это ошибка в статье.

В объявлении элемента данных допускается только скобка-или-равный-инициализатор. Инициализации d, p и y верны, но не s. Обоснование этого состоит в том, что использование списка-выражений приведет к неоднозначности объявления с объявлением функции, а также вызовет конфликты с поиском имени в теле класса.

person 0x499602D2    schedule 05.06.2015
comment
Спасибо. Не могли бы вы дать ссылку на стандарт? Я думаю, что вы указали истинную причину такого поведения. - person Constructor; 05.06.2015
comment
@Constructor Стандарт не дает явного объяснения. Правило просто находится в [class.mem] / p4. Кроме того, stackoverflow.com/a/24837330/701092 - person 0x499602D2; 05.06.2015
comment
Вы имеете в виду [class.mem] / p5? И большое спасибо за эту ссылку! Это очень хорошо. - person Constructor; 05.06.2015
comment
@Constructor Я использую последнюю версию n4431. Вероятно, вы используете n3242. - person 0x499602D2; 05.06.2015
comment
О, да. n3337, если быть точным. - person Constructor; 05.06.2015
comment
Я обычно использую стандартные черновики, близкие к C ++ 11, для проверки чистых возможностей C ++ 11. - person Constructor; 05.06.2015

Пример от Бьярна Страуструпа:

class A {
    public:
        A() {}
        A(int a_val) : a(a_val) {}
        A(D d) : b(g(d)) {}
        int a = 7;
        int b = 5;  
    private:
        HashingFunction hash_algorithm{"MD5"};  // Cryptographic hash to be applied to all A instances
        std::string s{"Constructor run"};       // String indicating state in object lifecycle
    };
person pr3sto    schedule 05.06.2015
comment
Спасибо за ссылку. - person Constructor; 05.06.2015