Удовлетворенная и смоделированная концепция?

Вступление

Стандарт определяет, что каждое понятие связано с двумя предикатами:

  1. предикат определяется: концепция удовлетворяется последовательностью аргументов шаблона, когда она оценивается как истина. Это почти синтаксическая проверка.
  2. предикат моделируется следующим образом: Считается, что последовательность Args шаблонных аргументов моделирует концепцию C, если Args удовлетворяет C ([temp.constr.decl]) и удовлетворяет всем семантическим требованиям (если таковые имеются), указанным в спецификации C. [res.on.requirements]

Для некоторых концепций четко выражены требования, которые позволяют моделировать удовлетворяющую концепцию. Пример [concept.assignable]

Модель LHS и RHS назначается из ‹LHS, RHS›, только если

  • addressof (lhs = rhs) == addressof (lcopy)
  • [...]

Но мне интересно, подразумевают ли синтаксические требования также неявно семантические требования.

Вопрос

Подразумевают ли синтаксические предикаты неявное требование к моделированию концепции?

Я вижу два вида неявных требований:

  1. Концепция удовлетворяется, потому что синтаксически проверенные выражения являются неоцененными выражениями, и такие выражения привели бы к неправильному формированию программы, если бы эти выражения не были неоцененными выражениями.
  2. Концепция удовлетворяется, потому что синтаксически проверенные выражения не оцениваются, но оценка этого выражения приведет к тому, что программа будет иметь неопределенное поведение.

Примеры

Например, давайте рассмотрим концепцию default_initializable, определенную здесь: [concept.default .init].

default_initializable удовлетворяется A<int>, но программа имеет неправильный формат, если переменная типа A<int> инициализирована по умолчанию (demo):

template <class T>
struct A { 
    A() {
       f(T{});
       }
    };

static_assert (default_initializable <A<int>>);  // A<int> satisfies default_initializable

A<int> a{}; //compile time error: f not declared in this scope

default_initializable удовлетворяется A, но инициализация по умолчанию A приводит к неопределенному поведению (когда инициализации по умолчанию не предшествует инициализация нуля) (демонстрация):

struct A { 
    int c;
    A() {
       c++;
       }
    };

static_assert (default_initializable <A>); // A satisfies default_initializable

auto p = new A;  //undefined behavior: indeterminate-value as operand of operator ++

person Oliv    schedule 25.06.2020    source источник
comment
default_initializable не имеет семантических требований, так что, наверное, не лучший пример? Как, я полагаю, ни одна из этих операций не демонстрирует неопределенного поведения, но это довольно утомительно, если вам придется повторять это буквально везде?   -  person Barry    schedule 25.06.2020
comment
@Barry Это как раз мой вопрос. default_initializable не имеет явных семантических требований. Но требуется ли, чтобы инициализация по умолчанию была правильно сформирована и не вызывала неопределенного поведения? Или default_initializable концепция чисто синтаксическая?   -  person Oliv    schedule 25.06.2020
comment
@Oliv: default_initializable не имеет явных семантических требований. Но требуется ли для этого, чтобы инициализация по умолчанию была правильно сформирована и не вызывала неопределенного поведения? Ваше первое предложение отвечает на второе.   -  person Nicol Bolas    schedule 26.06.2020


Ответы (1)


концепция удовлетворяется последовательностью аргументов шаблона, когда она оценивается как истинная. Это почти синтаксическая проверка.

Нет, это почти ничего: это это синтаксическая проверка. Ограничения, указанные в предложении requires (например), подтверждают, что конкретный синтаксис является допустимым синтаксисом для этого типа. Это все, что означает удовлетворение концепции.

Подразумевают ли синтаксические предикаты неявное требование к моделированию концепции?

... нет. Если бы выполнение концепции также подразумевало моделирование концепции, тогда в стандарте не потребовались бы для этого другие термины.

Смысл такого различия заключается в признании того факта, что функция языка концептов не может определять все требования, которые концепты как концепт должны инкапсулировать. Итак, удовлетворение концепции - это всего лишь языковая часть, в то время как моделирование концепции включает в себя вещи, которые язык не может сделать.

Но этот вопрос отчасти отличается от того, что показывают ваши два примера. Ваши примеры представляют собой разницу между допустимым синтаксисом и могут быть скомпилированы / выполнены. Удовлетворение концепции заботит только первое. И моделирование концепции заботится только о последнем в той степени, что указанное семантическое поведение явно указано.

В стандарте нет ничего о неявных семантических требованиях. Нет никаких утверждений о влиянии, чтобы все выражения / утверждения в концепции могли быть скомпилированы и / или выполнены, чтобы ее можно было смоделировать. И не для этого.

Как бы мы ни старались делать вид, что это нечто большее, концепция в том виде, в котором она существует в C ++ 20, является не более чем, чем более удобный механизм для выполнения SFINAE. SFINAE не может проверить корректность компилируемого / исполняемого содержимого некоторых выражений, так же как и концепции. И концепции также не пытаются делать вид, что это возможно.

person Nicol Bolas    schedule 26.06.2020
comment
Какое разочарование ... Я надеялся, что эту концепцию даже без аксиом можно будет рассматривать как способ введения более сильных типов, которые используются в теориях типов. Я бы предпочел заключить контракт! - person Oliv; 26.06.2020