Явные конструкторы по умолчанию в 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 "Явные конструкторы по умолчанию и инициализация списка копирования", которая имеет полезный фон.