Прямая Инициализация против Инициализации Значения

Я программист на C, пытаюсь выучить C++11 и столкнулся с тем, чего не понимаю. Из того, что я могу сказать, следующая проблема - это разница между инициализацией значения и прямой инициализацией.

Следующий фрагмент кода не компилируется с использованием Visual Studio:

class TestClass {
    int _val;
    std::string _msg;
public:
    TestClass(int, std::string);
    void action();
};

TestClass::TestClass(int val, std::string msg)
    : _val{val}, _msg{msg}
{
}

void TestClass::action()
{
    std::cout << _msg << _val << std::endl;
}

Это дает мне:

ошибка C2797: 'TestClass::_msg': инициализация списка внутри списка инициализатора элемента или не статического инициализатора элемента данных не реализована

Тем не менее, изменение

TestClass::TestClass(int val, std::string msg)
    : _val{val}, _msg{msg}

в

TestClass::TestClass(int val, std::string msg)
    : _val{val}, _msg(msg)

исправляет мою проблему В чем разница между этими двумя формами инициализации и когда одна из них должна использоваться поверх другой? Меня убеждают, что я должен использовать инициализацию значений всякий раз, когда имеем дело с явными типами.

1 ответ

Решение

Это деталь реализации компилятора Visual C++. Вы можете прочитать больше об этой ошибке здесь. На странице указано:

Компилятор C++ в Visual Studio не реализует инициализацию списка ни в списке инициализатора элемента, ни в не статическом инициализаторе элемента данных

Ваш код пытается реализовать первый случай. Решение, которое вы предложили, решает эту проблему, но если вы все же предпочитаете использовать список инициализаторов в конструкторе, вы можете сделать это:

TestClass::TestClass(int val, std::string msg)
    : _val{val}, _msg(std::string{msg})

Который будет работать, как вы намерены.

Другие вопросы по тегам