Неявные варианты выражения понятия обрабатываются неправильно?

Неявные варианты выражения require должны соответствовать следующим требованиям:

Требует выражения, которое использует выражение, которое не является модификацией для некоторого постоянного операнда lvalue, также неявно требует дополнительных вариантов этого выражения, которые принимают непостоянное lvalue или (возможно, постоянное) rvalue для данного операнда, если такой вариант выражения не требуется явно. с различной семантикой.

Эти неявные варианты выражений должны соответствовать тем же семантическим требованиям, что и объявленное выражение. Степень, в которой реализация проверяет синтаксис вариантов, не указана.

template<class T>
concept C = requires(T a, T b, const T c, const T d)
{
    c == d;           // expression #1: does not modify the operands
    a = std::move(b); // expression #2: modifies both operands
    a = c;            // expression #3: modifies the left operand `a`
};

// Expression #1 implicitly requires additional expression variations that
// meet the requirements for c == d (including non-modification),
// as if the following expressions had been declared as well:

// ------ const == const ------- ------ const == non-const ---
//                                         c  ==           b;
//            c == std::move(d);           c  == std::move(b);
// std::move(c) ==           d;  std::move(c) ==           b;
// std::move(c) == std::move(d); std::move(c) == std::move(b);

// -- non-const == const ------- -- non-const == non-const ---
//           a  ==           d;            a  ==           b;
//           a  == std::move(d);           a  == std::move(b);
// std::move(a) ==           d;  std::move(a) ==           b;
// std::move(a) == std::move(d); std::move(a) == std::move(b);

// Expression #3 implicitly requires additional expression variations that
// meet the requirements for a = c
// (including non-modification of the second operand),
// as if the expressions a = b (non-constant lvalue variation)
// and a = std::move(c) (const rvalue variation) had been declared.

// Note: Since expression #2 already requires the non-constant rvalue variation
// (a == std::move(b)) explicitly, expression #3 does not implicitly require it anymore.

// The type T meets the explicitly stated syntactic requirements of
// concept C above, but does not meet the additional implicit requirements
// (i.e., T satisfies but does not model C):
// a program requires C<T> is ill-formed (no diagnostic required).
struct T
{
    bool operator==(const T&) const { return true; }
    bool operator==(T&) = delete;
};

Но, похоже, ни один из последних компиляторов не следует этому правилу (https://godbolt.org/z/84rK7rGTb - C<T> должно оцениваться как false). Я что-то пропустил?

«Степень, в которой реализация проверяет синтаксис вариантов, не указана».

BoP 16.06.2024 19:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
96
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В случае сомнений смотрите непосредственно стандарт: https://eel.is/c++draft/concepts.equality#8

См. https://eel.is/c++draft/concepts.equality#8 акцент мой:

[Пример 4: Следующий тип T отвечает явно указанным синтаксическим требованиям понятия C выше, но не соответствует дополнительным неявным требованиям:

   struct T {
     bool operator==(const T&) const { return true; }
     bool operator==(T&) = delete;
   };

T не соответствует неявным требованиям C, поэтому T удовлетворяет, но не моделирует C. Поскольку реализациям не требуется проверять синтаксис неявных требований, неясно, диагностируется ли реализация как неправильно сформированная программа, требующая C<T>. — конец примера]

Так что никакой диагностики не требуется.

Ответ принят как подходящий

Цитирую вашу цитату:

Степень, в которой реализация проверяет синтаксис вариантов, не указана.

...

// a program requires C<T> is ill-formed (no diagnostic required).

Компилятору не требуется проверять при проверке C<T>, что для T a, ba == b разрешено.

Существует разница между удовлетворением концепции и моделированием концепции. Удовлетворение концепции CT определяется тем, оценивается ли C<T> до true. Обратите внимание, что правила вычисления выражения requires ничего не говорят о проверке неявных вариаций выражения. На самом деле было бы неправильно, если бы компилятор оценивал от C<T> до false в вашем примере.

Моделирование концепции — это понятие, которое, как правило, не может быть проверено компилятором. Концепция моделируется, когда она удовлетворяется и тип ведет себя так, как «должен». Например, следующий тип

struct U { bool operator==(U const&) const { return false; } };

удовлетворяет std::equality_comparable (поскольку a == b, a != b и т. д. хорошо сформированы), но не моделирует std::equality_comparable, поскольку == не является разумным понятием равенства (оно не рефлексивно). Неявные вариации выражений, требуемые концепцией, являются частью того, что означает моделирование концепции, но не тем, что означает ее удовлетворение. Они выходят за рамки того, что требуется проверить компилятору.

Если компилятор реализует проверку того, моделируют ли типы концепцию, это (опять же) не должно проявляться как концепция, которая фактически оценивается как false. Вместо этого он может выдать предупреждение или ошибку, когда заметит, что вернулась оценка концепции true, но концепция на самом деле не смоделирована. Я не уверен, что какой-либо компилятор делает это для какой-либо концепции на практике.

Вы имеете в виду, что оценка C<T> должна быть true? Стандарт, упомянутый Джародом, говорит, что он не указан.

김선달 17.06.2024 07:22

@김선달 Нет, там написано не это. Там говорится, что программа, требующая C<T>, может быть диагностирована как неправильно сформированная. Плохо сформированная программа не подразумевает C<T> вычисления для false. Если есть диагноз, он должен быть примерно таким: «C<T> оценивается как true, но T не моделируется C из-за несоответствия неявным требованиям вариации выражения». Опять же, нет возможности учитывать неявные вариации выражений при вычислении выражения requires.

HTNW 17.06.2024 08:23

Цитируем стандарт: неопределенное поведение возникает, когда ограничение удовлетворяется, но не моделируется, согласно eel.is/c++draft/res.on.requirements . Когда концепция используется в логическом выражении, она оценивается путем проверки того, удовлетворяется ли концепция, согласно eel.is/c++draft/temp.names#9 . Удовлетворение однозначное: оно сводится к подстановке параметров шаблона в выражение, определяющее концепцию, согласно eel.is/c++draft/temp.constr.constr#temp.constr.atomic-3. Если тип T удовлетворяет концепции C, но не моделирует ее, это означает, что C<T> оценивается как true.

HTNW 17.06.2024 08:38

Теперь я понимаю. Спасибо!

김선달 17.06.2024 08:41

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