Понимание концепций. Проверить, является ли член статическим
Допустим, у нас есть простая концепция, например:
template <typename T>
concept MyConcept = requires {
T::value == 42;
};
В моем понимании концепция говорит о том, что если код действителен для типа Т, то я прохожу. Итак, ДОЛЖЕН быть статическим членом, верно?
у меня естьstruct
struct Test { int value = 0; }
и следующая функция шаблона
template <MyConcept T>
void call() { /*...*/ }
и когда я пытаюсь сделать это:
int main()
{
call<Test>();
}
Оно работает!
И вопрос: почему это работает?Test::value == 42
не является допустимым кодом для типаTest
.
Я нашел способ исправить это, например:
template <typename T>
concept MyConcept = requires {
*(&T::value) == 42;
};
И он «работает» так, как ожидалось:
<source>:6:20: note: the required expression '((* & T::value) == 42)' is invalid
И эта концепция работает для статическихvalue
только так и должно быть. Но почемуT::value == 42
работа?
Богболт: https://godbolt.org/z/d3GPETEq9
UPD: + пример https://godbolt.org/z/d8qfzK9b6
1 ответ
И эта концепция работает только для статического значения, как и должно быть. Но почему
T::value == 42
работа?
Потому что на самом деле в правиле есть исключение, которое, по вашему мнению, приведет к сбою.
Правило из [expr.prim.id.general]/3 , акцент мой:
Идентификационное выражение , обозначающее нестатический элемент данных или нестатическую функцию-член класса, может использоваться только:
- как часть доступа к члену класса, в котором выражение объекта относится к классу51 члена или классу, производному от этого класса, или
- для формирования указателя на член ([expr.unary.op]), или
- если это id-выражение обозначает нестатический член данных и появляется в невычисленном операнде.
[Пример 3 :
struct S { int m; }; int i = sizeof(S::m); // OK int j = sizeof(S::m + 42); // OK
— конец примера]
Вот этот третий пункт: можно использовать как невычисленный операнд. Все выражения, которые вы регистрируете в требовании, не оцениваются. ТакT::value
отлично работает для нестатических элементов данных.