Концепция с несколькими аргументами шаблона - PullRequest
4 голосов
/ 26 апреля 2020

Я пытаюсь использовать концепции C ++ 20, чтобы начать с ними знакомство. Я чувствую себя довольно комфортно с простыми концепциями, например со стандартной концепцией movable. Я могу написать что-то вроде этого (во всех примерах я предполагаю, что я using namespace std, и я включил <concepts> и любой другой необходимый заголовок):

template<movable T>
int foo (T obj);

И убедитесь, что при вызове этой функции переданный объект obj можно переместить. Я могу написать это даже в более длинной форме:

template<typename T>
requires movable<T>
int foo (T obj);

И результат будет таким же (я думаю).

Но теперь давайте посмотрим на другую концепцию, такую ​​как same_as. same_as принимает параметр 2 шаблонов (2 типа для сравнения), поэтому я могу написать:

template<typename T>
requires same_as<T, string>
int bar (T obj);

И теперь T равно string. Но как я могу написать это в более короткой форме? Я пытался, и я могу написать это (как я и ожидал):

template<same_as<string> T>
int bar (T obj);

Но каково формальное правило этой формы?

Является ли name (T) параметра шаблона функции, введенного в качестве первого аргумента шаблона концепции? Или, может быть, как в прошлом? Я не знаю, очень мало информации об этом топи c. Я имею в виду, что в этом примере это не имеет значения, потому что same_as<A, B> семантически эквивалентно same_as<B, A>, но в некоторых случаях порядок имеет значение.


Я знаю, что есть вопросы с похожими названиями, такими как , этот , но он задает другое.

Это ресурсы, из которых я пытался получить информацию , но не удалось: cppReference , cppModernes , open-std (я просматривал годы 2018, 2019 и 2020) и этот пост .

1 Ответ

5 голосов
/ 26 апреля 2020

Но что является формальным правилом этой формы?

Правило (в которое вы правильно догадались) описано в [temp.param] / 4 :

A ограничение типа Q, обозначающее концепцию C, может использоваться для ограничения пакета параметров типа или шаблона, определенного в контексте T с выражением ограничения E, определенным как следующим образом. Если Q имеет форму C<A1, ⋯, An>, то пусть E′ будет C<T, A1, ⋯, An>. В противном случае пусть E′ будет C<T>. Если T не является пакетом, то E - это E′, в противном случае E - это (E′ && ...). Это выражение-ограничение E называется немедленно объявленным ограничением из Q для T. Понятие, обозначенное ограничением типа , должно быть понятием типа ([temp.concept]).

С примерами в следующем абзаце:

параметр типа , начинающийся с ограничение типа , вводит немедленно объявленное ограничение ограничение типа для параметра. [Пример:

template<typename T> concept C1 = true;
template<typename... Ts> concept C2 = true;
template<typename T, typename U> concept C3 = true;

template<C1 T> struct s1;               // associates C1<T>
template<C1... T> struct s2;            // associates (C1<T> && ...)
template<C2... T> struct s3;            // associates (C2<T> && ...)
template<C3<int> T> struct s4;          // associates C3<T, int>
template<C3<int>... T> struct s5;       // associates (C3<T, int> && ...)

- конец примера]

Вы также можете думать о template <C T> как о сокращении для template <C<> T>, а затем просто введите параметр типа T всегда вставляется в первый аргумент концепции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...