Size: a a a

2020 September 01

N

Neargye in pro.cxx
Александр Караев
опечатка, all public
https://godbolt.org/z/c6Pafq

gcc  тут не прав получается?

почему я задаю куча вопрос, я ориентировался на прополз, и там не было про алл паблик

a type that is literal, has strong structural equality (15.9.1), has no
mutable or volatile subobjects, and in which if there is a defaulted
member operator<=>, then it is declared public,


было вот так
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
В чем вообще проблема NTTP параметров?

Рассмотрим простую функцию template <T value> void f();

До C++20 в качестве T мог выступать один из небольшого множества типов. Особенность этого множества состояла в том, что можно два объекта типа T сравнить, убедиться в их эквивалентности. В частности, f<2> и f<1+1> оказывались одинаковыми инстанцированиями, так как 2==1+1. А ещё от них от всех можно посчитать хеш по алгоритму, выбранному компилятором.

Теперь допустим, что мы хотим сделать T = std::string (допустим также, что строка у нас уже вся обмазана constexpr). Как компилятору проверить, что f<std::string("1")> и f<std::string("1")> - это одна и та же функция? Логично, что для этого он должен уметь сравнивать в constexpr строки. Более того, так как шаблоны кэшируются, то очень хорошо бы ещё уметь и хешировать такие параметры (хеш-таблица быстрее дерева). То есть при инстанцировании очередной f<some_string> компилятор должен поискать среди уже проинстанцированных f<..> такую же.

Это приводит к необходимости делать подобие constexpr hash + constexpr operator<=>, который должен быть написан автором типа T (std::string или какой-то used-defined). Здесь и засада. Пользователь может написать некорректную реализацию, что приведёт к UB при компиляции, которое невозможно диагностировать. Что просто сломает компилятор.

Поэтому решили сделать требования типа all public и прочее - компилятор считает такие типы просто последовательностью более примитивных типов, от которых он умеет считать хеш и сравнивать.
> Здесь и засада. Пользователь может написать некорректную реализацию, что приведёт к UB при компиляции, которое невозможно диагностировать. Что просто сломает компилятор.

Что то не пойму, UB в constexpr как раз диагностируются компилятором. В чём тут отличие от обычной constexpr foo функции?
источник

АК

Александр Караев... in pro.cxx
да, это было в предпоследней версии пропозала. поменяй gcc на 10-й и код не скомпилируется
источник

N

Neargye in pro.cxx
Александр Караев
да, это было в предпоследней версии пропозала. поменяй gcc на 10-й и код не скомпилируется
О! спасибо! многое прояснилось
@unterumarmung  тебе тоже спасибо за форс стандарта
источник

АК

Александр Караев... in pro.cxx
Побитый Кирпич
> Здесь и засада. Пользователь может написать некорректную реализацию, что приведёт к UB при компиляции, которое невозможно диагностировать. Что просто сломает компилятор.

Что то не пойму, UB в constexpr как раз диагностируются компилятором. В чём тут отличие от обычной constexpr foo функции?
если ты напишешь свой operator<=>, который не даст нужного ordering, то ты можешь сломать какой-нибудь std::map<> внутри компилятора
источник

N

Neargye in pro.cxx
Побитый Кирпич
> Здесь и засада. Пользователь может написать некорректную реализацию, что приведёт к UB при компиляции, которое невозможно диагностировать. Что просто сломает компилятор.

Что то не пойму, UB в constexpr как раз диагностируются компилятором. В чём тут отличие от обычной constexpr foo функции?
Пресдавть что оператор сравнение в констехпр будет возврашать рандомное число)
источник

АК

Александр Караев... in pro.cxx
Побитый Кирпич
> Здесь и засада. Пользователь может написать некорректную реализацию, что приведёт к UB при компиляции, которое невозможно диагностировать. Что просто сломает компилятор.

Что то не пойму, UB в constexpr как раз диагностируются компилятором. В чём тут отличие от обычной constexpr foo функции?
https://t.me/ProCxx/300860
=)
(это не про финальную версию пропозала, но всё же)
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
если ты напишешь свой operator<=>, который не даст нужного ordering, то ты можешь сломать какой-нибудь std::map<> внутри компилятора
Ясно, вижу вообщем минус очевидный такого подхода, что он банит валидные типы, у которых тривиальное сравнение, но есть приватные члены. В этом и эвристичность подхода.
источник

АК

Александр Караев... in pro.cxx
Александр Караев
https://t.me/ProCxx/300860
=)
(это не про финальную версию пропозала, но всё же)
там Андрей Давыдов расписал всё по полочкам ниже, советую почитать
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
там Андрей Давыдов расписал всё по полочкам ниже, советую почитать
Дак я согласен на default оператор сравнения
источник

ПК

Побитый Кирпич... in pro.cxx
Я не согласен на all public
источник

АК

Александр Караев... in pro.cxx
Побитый Кирпич
Дак я согласен на default оператор сравнения
а я не согласен на default - нафига мне такое сравнение для той же std::string
источник

АК

Александр Караев... in pro.cxx
пусть лучше потом допилят идею, чтобы std::string без модификации стал NTTP
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
а я не согласен на default - нафига мне такое сравнение для той же std::string
Чтоб контент сравнить строки
источник

АК

Александр Караев... in pro.cxx
Побитый Кирпич
Чтоб контент сравнить строки
так default для строки сравнит два указателя, два size и два capacity.
указатели могут указывать на одинаковые строки по разным адресам, а capacity вообще может быть любым.
что тебе даст такое сравнение?
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
пусть лучше потом допилят идею, чтобы std::string без модификации стал NTTP
Да можно наверн просто сделать std::fixed_string и чтоб она могла неявно конструироваться от constexpr строки.
источник

АК

Александр Караев... in pro.cxx
Побитый Кирпич
Да можно наверн просто сделать std::fixed_string и чтоб она могла неявно конструироваться от constexpr строки.
и fixed_tuple, и fixed_vector...
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
так default для строки сравнит два указателя, два size и два capacity.
указатели могут указывать на одинаковые строки по разным адресам, а capacity вообще может быть любым.
что тебе даст такое сравнение?
Дак у строки он как раз не дефолт
источник

ПК

Побитый Кирпич... in pro.cxx
Поэтому не подходит под это требование
источник

АК

Александр Караев... in pro.cxx
а, я тебя понял
источник