Больше допустимых типов для нетиповых аргументов шаблонов

ldvsoft
ldvsoft

Предлагаю разрешить передавать в качестве нетиповых параметров шаблонов большее множество типов, например POD от допустимых типов (включая так или иначе std::tuple, std::pair), а также некоторые типы из стандартной библиотеки (std::optional от допустимых типов).

Причины: мы и так уже можем передавать в шаблон несколько значений по отдельности. Почему нельзя передавать некоторую логично их объединяющую структуру, имеющую всю необходимую семантику (скажем, constexpr-конструкторы, операторы равенства и прочее)? Мы и так уже можем написать два шаблона (один с аргументом, другой без него); а также писать constexpr if. Мы могли бы писать один шаблон с constexpr-if на наличие значения в std::optional?

Возможно это потребует введения каких-то правил, trait-ов для описания, какие типы допустимы. Мне кажется можно обойтись и относительно небольшим расширением доступных типов.

Единственными препятствием я вижу манглинг, но он должен быть отдан на решение компиляторам, которые могут хранить хоть байтовое представление значения; а также необходимость компилятору в момент компиляции выполнения constexpr-кода в выводе типов, но компиляторы и сейчас выполняют эти вычисления, но только на целочисленных типах и аналогичных.

5
рейтинг
10 комментариев
Andrey Davydov
Вопрос для затравки -- а использовать float Вы хотите разрешить?
Для expression template parameters важно определить равенство, это будет пользовательский operator == или почленное сравнение структур вплоть до примитивных типов? И с тем и другим подходом есть проблемы.
Andrey Davydov
ldvsoft
Andrey Davydov, я, если честно, плохо понимаю конкретные причины против использования float, но кажется надо быть крайне аккуратным с точностью вычислений, оно может того не стоить.

А если мы скажем, что требуем trivial constexpr operator ==? Тогда он сводится к сравнению полей. Я как раз указал, что не очень понятно, какие именно требования накладывать, и да, это требует обсуждения, но как раз ради этого я и выложил идею. Обсудим, может работать будем.
ldvsoft
Andrey Davydov
ldvsoft,
> я, если честно, плохо понимаю конкретные причины против использования float
template<auto> struct X {};
is_same_v<X<+0.f>, X<-0.f>> это true или false?
is_same_v<X<Nan>, X<Nan>> это true или false?
> А если мы скажем, что требуем trivial constexpr operator ==?
А что это такое? Сейчас есть только builtin, если предположить что появится возможность генерировать операторы сравнения, то возникнет следующий вопрос. Вот есть весь такой из себя constexpr класс std::string_view, но operator == у него, понятное дело, user defined. Значит, его все равно нельзя будет использовать как expression template parameter. И std::optional нельзя, по той же причине.
Andrey Davydov
ldvsoft
Andrey Davydov, вот и надо думать и обсуждать. Спасибо за дельные комментарии.
ldvsoft
Andrey Davydov
ldvsoft, По-моему, если не получается придумать простое и логичное для пользователя поведение, то лучше вообще не добавлять фичу в язык, если только нет сильного мотивирующего примера, зачем это надо. Я такого не вижу. Вы говорили про optional<int>, не уверен что, угадал, какую задачу Вы решали, но скажем, мы хотим, что у класса X было static const поле типа optional<int>. Я бы это сделал так:
template<typename> class X;
template<int I> class X<integral_constant<int, I>>
{
static const optional<int> value { I };
};
template<> class X<nullopt_t>
{
static const optional<int> value {};
};
Andrey Davydov
Павел Корозевцев
А можно мне пример, когда нужно передать "сложный" тип как аргумент шаблона, но нельзя для этих целей заиспользовать constexpr?
Павел Корозевцев
ldvsoft
Павел Корозевцев, кажется это два разных вопроса. Нужно было мне передать в шаблон опциональное число, у которого нет "исключительного" значения чтобы его считать отсутствием. Можно передать bool + value, но их приходится писать в два аргумента, а хочется вообще написать std::optional. constexpr здесь только при том что внутри шаблона можно разобрать случай наличия-отсутствия значения в compile time.
ldvsoft
d-yaroshev
Этот вопрос спрашивали на CppCon последнем: youtu.be/JYG5LFHkUuE (не могу сейчас указать минуту).

Страуструп сказал что проблема есть, это единственное место в языке где можно отличить пользовательские типы от встроенных. Но поскольку у нее очень узкая область применения. никто этим не занимается.
d-yaroshev
Andrey Davydov
Недавние подвижки по данному вопросу:
1. je4d.s3.amazonaws.com/D0732R0-wip.pdf -- разрешить использовать в качестве expression template parameters классы с compiler generated `operator <=>`.
2. github.com/ldionne/wg21/blob/master/generated/d0424r2.pdf -- отдельное правило для string literals.
Andrey Davydov
ldvsoft
Andrey Davydov, Спасибо огромное, почитаю. <=> кажется особо удачной кандидатурой, но он, к сожалению, сам по себе не даст использовать std::optional/std::variant.
ldvsoft
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).