Значения по умолчанию при возврате класса из списка инициализаторов (vs2015 против vs2017) - PullRequest
0 голосов
/ 15 октября 2018

Я ищу объяснение следующего наблюдения.Начиная с vs2017 короткий код, о котором идет речь, читается следующим образом:

#include <iostream>

class Range
{
public:
  double min = 0; // some default values here
  double max = 1;

  double getRange() const {return max-min;};
};

Range makeRange(double a, double b)
{
  return {a,b}; // the initializer list return in question
}

int main()
{
  const auto x = makeRange(4.0,5.0); // some example application
  std::cout << x.min << ", " << x.max << std::endl;
}

. В этом случае класс Range предоставляет значения по умолчанию для «min» и «max» и может быть инициализирован списком инициализаторов из «makeRange».,Этот код компилируется и работает в VS2017.

В VS2015 он не компилируется (ошибка C2440: «возврат»: невозможно преобразовать «список инициализаторов» в «диапазон»).Однако, если значения по умолчанию удаляются так, что

class Range
{
public:
  double min;
  double max;

  double getRange() const {return max-min;};
};

, он компилируется и работает в vs2015.Это все еще будет компилироваться в VS2017.Тем не менее, значения по умолчанию не определены (я думаю).Как только конструктор добавлен так, что есть значения по умолчанию

  Range():min(0),max(0){};

, компиляция в VS2017 завершится неудачно.Итак, есть два вопроса по этому поводу:

  1. Я предположил, что списки инициализаторов, поддерживаемые VS2015.Почему первый код не компилируется в VS2015?Почему это происходит при удалении значений по умолчанию?
  2. Почему определение конструктора по умолчанию разрушает функциональность списка инициализатора в VS2017?Настройки по умолчанию у самих участников явно работали.

1 Ответ

0 голосов
/ 16 октября 2018

Вы используете агрегатная инициализация .Это, конечно, требует, чтобы Range был агрегатным типом.Определение агрегата было много изменено между различными версиями стандарта.

Таким образом, в C ++ 11 класс с инициализаторами-членами по умолчанию не мог быть агрегатом, но начиная с C ++ 14 онможет быть.Похоже, что VS2015 использует первое определение, а VS2017 - второе.

Класс с предоставленными пользователем конструкторами не является агрегатом ни в одной версии стандарта.

...