C ++ вариант конвертирующего конструктора с bool - PullRequest
0 голосов
/ 01 февраля 2019

Вкл. cppreference (4) конструктор преобразования описывается следующим образом:

Конструктор преобразования.Создает вариант, содержащий альтернативный тип T_j, который был бы выбран разрешением перегрузки для выражения F(std::forward<T>(t)), если бы была перегрузка мнимой функции F(T_i) для каждого T_i из Types... в области действия одновременно,за исключением того, что:

  • Перегрузка F(T_i) рассматривается только в том случае, если объявление T_i x[] = { std::forward<T>(t) }; действительно для некоторой изобретенной переменной x;
  • Если T_i (возможно, cv-квалифицирован) bool, F(T_i) рассматривается только в том случае, если std:remove_cvref_t<T> также bool.

Iособенно интересует второй пункт пули относительно bool.В примере написано, что:

std::variant<std::string, bool> y("abc"); // OK, chooses string; bool is not a candidate

Я сейчас тестировал тот же код с помощью clang 7.0.0 ( godbolt ), gcc.8.2 ( godbolt ) и VS2017.И мне интересно, почему содержащийся альтернативный тип является bool (для всех трех компиляторов), а не std :: string, как описано в cppreference.Это ошибка в стандартных библиотеках всех трех компиляторов?

Я также нашел следующий документ: P0608R3 .Означает ли это, что изменения (две маркированные точки) в списках cppreference только предлагаются, но еще не являются частью официального стандарта?

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

В каждой версии стандарта C ++ есть ошибки.Сотни из них.

Реализации C ++ стремятся быть полезными, поэтому они не порабощенно придерживаются опубликованного стандартного текста.Нет причин поддерживать совместимость «ошибка за ошибкой» с листом бумаги.

(В качестве крайнего примера, до C ++ 17 стандарт технически требовал, чтобы <int> в std::vector<int> v; был проанализирован как header-name , а затем отклонено, потому что оно не находится внутри директивы * 1009. * Само собой разумеется, что no компилятор сделает это.)

Cppreferenceтакже стремится быть полезным.Поэтому мы не поддерживаем совместимость «ошибка за ошибкой» со стандартами.Когда фрагмент текста впервые появился на листе бумаги, опубликованном ISO, бесполезен (за исключением стандартных историков, возможно);как программисты, мы заботимся о том, что мы получаем, когда используем -std=c++17, или каков бы ни был эквивалентный флаг вашей реализации.В результате наша документация предназначена для гипотетически полной и правильной реализации каждого стандарта C ++, а также всех последующих исправлений и пояснений, применимых к этому стандарту. * Мы используем текущие реализации в качестве доказательства того, что такая гипотетическая реализация будетdo.

Когда для конкретного изменения существует нет текущей реализации, мы оцениваем природу изменения, чтобы предсказать, как реализации будут его обрабатывать.Изменения в базовом языке, предназначенные для обратной силы, помечаются как отчеты о дефектах, которые облегчают вызов (хотя иногда они не доходят до конца, а , что отсутствует в маркировке).Изменения в библиотеке не сопровождаются постоянно применяемыми метками «DR», поэтому вызов остается за нами.

В данном конкретном случае, хотя P0608 не помечен как отчет о дефектах, он исправляет крайне сомнительныеповедение в C ++ 17 вскоре после его публикации.Кроме того, крайне нежелательно, чтобы код, подобный std::variant<std::string, bool> x = "abcd";, молча изменял значение в той же реализации в зависимости от стандартного режима.Код, основанный на std::variant, также редко встречается в дикой природе (отчасти, поэтому комитет даже одобрил «критические» изменения в первую очередь).В результате я предсказал, что документ в конечном итоге будет применен задним числом, и соответствующим образом задокументировал его.


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

0 голосов
/ 01 февраля 2019

P0608R3 был принят в Сан-Диего.Его формулировка была применена к рабочему проекту - вы можете увидеть новую формулировку в [option.ctor] / 12 .

. Как часть этого изменения, мотивирующий пример:

variant<string, bool> x = "abc";

Теперь содержит string (в c ++ 20), тогда как раньше он содержал bool (в c ++ 17).Значение этого примера изменяется между стандартными версиями.

Просто ни одна из стандартных библиотек еще не реализовала это изменение.Это очень недавно.Он указан как неполный на страницах libstdc ++ и libc ++ .Но, как вы можете видеть, есть множество функций C ++ 20, которые еще не были реализованы.Хорошая новость в том, что все еще в начале 2019 года, и времени достаточно.

...