Понимание концепций. Проверить, является ли член статическим

Допустим, у нас есть простая концепция, например:

      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отлично работает для нестатических элементов данных.

Другие вопросы по тегам