В C ++ 17 пустые типы тегов в стандартной библиотеке теперь имеют конструкторы по умолчанию, помеченные explicit
и также = default
, Например, std::piecewise_construct_t
теперь определяется как
struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
Мой вопрос просто, что является причиной этого изменения с C ++ 14? Что означает явно заданный по умолчанию явный конструктор по умолчанию (!) Для пустого класса?
(Чтобы не быть помеченным как обманщик: этот вопрос с 2010 года спрашивает о назначении явных конструкторов по умолчанию, но это было до C ++ 11 и давным-давно, так что ситуация, вероятно, изменилась. Этот вопрос является более поздним, но, похоже, ответ предполагает, что агрегатная инициализация будет выполняться независимо от присутствия конструктора по умолчанию, поэтому мне любопытно узнать причину этого изменения в последнем стандарте.)
Обоснование изменения библиотеки находится в 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 «Явные конструкторы по умолчанию и инициализация списка копирования», который имеет полезный фон.
Других решений пока нет …