Явные конструкторы по умолчанию в C++17

В C++17 пустые типы тегов в стандартной библиотеке теперь имеют конструкторы по умолчанию, помеченные explicit и также = default, Например, std::piecewise_construct_t теперь определяется как

struct piecewise_construct_t { explicit piecewise_construct_t() = default; };

Мой вопрос просто, что является причиной этого изменения с C++14? Что означает явно заданный по умолчанию явный конструктор по умолчанию (!) Для пустого класса?

(Чтобы не быть помеченными как дураки: этот вопрос от 2010 года задает вопрос о назначении явных конструкторов по умолчанию, но это было до C++11 и давным-давно, так что ситуация, вероятно, изменилась. Этот вопрос более свежий, но кажется, что ответ предполагает, что агрегатная инициализация будет выполняться независимо от присутствия конструктора по умолчанию, поэтому мне любопытно узнать причину этого изменения в последнем стандарте.)

1 ответ

Решение

Обоснование для изменения библиотеки в LWG 2510 "Типы тегов не должны быть DefaultConstructible ":

std::experimental::optional по определенным причинам указывает его nullopt типа не быть DefaultConstructible, Это не делает для своего типа тега in_place_t и ни один из стандартов не подходит для любого из его типов тегов. Это оказывается очень прискорбно, рассмотрим следующее:

#include <memory>
#include <array>

void f(std::array<int, 1>, int) {} // #1
void f(std::allocator_arg_t, int) {} // #2

int main()
{
  f({}, 666); // #3
}

Звонок на #3 неоднозначен. Еще хуже то, что, если перегрузка #1 устранена, вызов работает просто отлично. Весь смысл типа тега заключается в том, что он либо должен быть упомянут в вызове, либо он должен быть перенаправленным аргументом, поэтому иметь возможность создавать подобный тип тега не имеет смысла.

Проблема LWG развивалась параллельно с CWG 1518 "Явные конструкторы по умолчанию и инициализация списка копирования", которая имеет полезный фон.

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