Почему мой компилятор не распознает "Bond () = default;"? - PullRequest
0 голосов
/ 09 ноября 2018

Пожалуйста, посмотрите на этот код

class Bond
{
    public:
        Bond(int payments_per_year, int period_lengths_in_months);
        Bond() = default;

    private:
        const int payments_per_year;
        const int period_length_in_months;
    };

int main()
{
    Bond b; // Error here
}

При попытке компиляции выдается ошибка:

ошибка C2280: 'Bond :: Bond (void)': попытка сослаться на удаленную функцию ".

Это не нарушение "правила 3", так как я добавил конструктор по умолчанию обратно.

Почему компилятор не распознает Bond() = default;?

Ответы [ 3 ]

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

Другое исправление - указать значение по умолчанию в объявлении констант:

const int payments_per_year = {12};

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

Это также очень гибкий способ упростить несколько вариантов конструктора.

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

На вас влияет раздел [class.default.ctor] p2 черновика стандарта C ++ (или [class.ctor] p5 в C ++ 11), в котором говорится:

Заданный по умолчанию конструктор по умолчанию для класса X определяется как удаленный, если:
...
- любой не вариантный нестатический элемент данных типа с определением констант (или массива)из них) без инициализации-скобки или равнозначного инициализатора не предусмотрен пользовательский конструктор по умолчанию,
...

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

const int payments_per_year{12};
const int period_length_in_months{48};

скобка-or-equal-initializer не требует фигурных скобок, мы можем видеть эту грамматику:

brace-or-equal-initializer:
    = initializer-clause
    braced-init-list

, но использование равномерной инициализации имеет некоторые преимущества, такие как сужение преобразований, неправильно сформированных что стоит привыкнуть к их использованию.

Как gcc, так и clang предоставляют более значимые диагнозыТики для этого см. в прямом эфире Godbolt .Иногда бывает полезно попробовать свой код на нескольких компиляторах, особенно если у вас есть минимальный тестовый пример, например, такой как clang:

 warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
    Bond() = default;
    ^
 note: default constructor of 'Bond' is implicitly deleted because field 'payments_per_year' of const-qualified type 'const int' would not be initialized
    const int payments_per_year;
              ^
...
0 голосов
/ 09 ноября 2018

Конструктор по умолчанию подавлен , поскольку существуют постоянные члены, которые должны быть явно инициализированы.

Следовательно, из-за этого подавления запись Bond() = default не не повторно вводит конструктор по умолчанию.

(Вы можете увидеть этот эффект, удалив все конструкторы в классе - вы все еще не можете создать экземпляр b.)

Если вы отбросите const от участников, тогда все будет хорошо; хотя другой альтернативой является предоставление инициализатора * или 1015 * для каждого элемента const;

const int payments_per_year = 2;
const int period_length_in_months = 6;

например.

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