Постоянный элемент справочных данных - PullRequest
0 голосов
/ 24 ноября 2018

Предположим, у нас есть структура с постоянным элементом справочных данных.

struct A {
    A() : i{5} {}
    const int& foo() const { return i; }
    const int& i;
};

Есть ли у вас какие-либо идеи, почему вывод для целочисленного литерала 5 отличается?

A a{};
std::cout << a.i << std::endl;
std::cout << a.foo() << std::endl;

5
-858993460

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Использование значения constant не literal.

Это Class::Class() : member{arg1, arg2, ...} {... прямая инициализация списка после c++11.

Попробуйте это:

 struct A {
    const int t = 5;
    A() : i{ t } { }
    const int& foo() const { return i; }
    const int& i;
};

int main()
{
    A a{};
    std::cout << a.i << std::endl;
    std::cout << a.foo() << std::endl;

    return 0;
}
0 голосов
/ 24 ноября 2018

Код плохо сформирован.Вы инициализируете i из буквального 5, что требует создания временного объекта и привязки к i.Временный будет уничтожен при выходе из конструктора, затем i будет зависать, любое последующее обращение к нему приведет к UB, что означает, что все возможно.

Из стандарта [class.base.init] / 8

Временное выражение, привязанное к элементу ссылки в mem-инициализаторе, плохоформируется.[Пример:

struct A {
  A() : v(42) { }   // error
  const int& v;
};

- конец примера]

КСТАТИ: Так как в стандарте указано, что плохо сформирован , компиляторы должны выдавать диагностическую информациюдля этого.Как поведение gcc (выдает предупреждение), так и clang (выдает ошибку) соответствуют друг другу;если VS2017 не выдает никакой диагностики, то он не соответствует стандарту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...