Вступление
Стандарт определяет, что каждое понятие связано с двумя предикатами:
- предикат определяется: концепция удовлетворяется последовательностью аргументов шаблона, когда она оценивается как истина. Это почти синтаксическая проверка.
- предикат моделируется следующим образом: Считается, что последовательность Args шаблонных аргументов моделирует концепцию C, если Args удовлетворяет C ([temp.constr.decl]) и удовлетворяет всем семантическим требованиям (если таковые имеются), указанным в спецификации C. [res.on.requirements]
Для некоторых концепций четко выражены требования, которые позволяют моделировать удовлетворяющую концепцию. Пример [concept.assignable]
Модель LHS и RHS назначается из ‹LHS, RHS›, только если
- addressof (lhs = rhs) == addressof (lcopy)
- [...]
Но мне интересно, подразумевают ли синтаксические требования также неявно семантические требования.
Вопрос
Подразумевают ли синтаксические предикаты неявное требование к моделированию концепции?
Я вижу два вида неявных требований:
- Концепция удовлетворяется, потому что синтаксически проверенные выражения являются неоцененными выражениями, и такие выражения привели бы к неправильному формированию программы, если бы эти выражения не были неоцененными выражениями.
- Концепция удовлетворяется, потому что синтаксически проверенные выражения не оцениваются, но оценка этого выражения приведет к тому, что программа будет иметь неопределенное поведение.
Примеры
Например, давайте рассмотрим концепцию 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 ++
default_initializable
не имеет семантических требований, так что, наверное, не лучший пример? Как, я полагаю, ни одна из этих операций не демонстрирует неопределенного поведения, но это довольно утомительно, если вам придется повторять это буквально везде? - person Barry   schedule 25.06.2020default_initializable
не имеет явных семантических требований. Но требуется ли, чтобы инициализация по умолчанию была правильно сформирована и не вызывала неопределенного поведения? Илиdefault_initializable
концепция чисто синтаксическая? - person Oliv   schedule 25.06.2020default_initializable
не имеет явных семантических требований. Но требуется ли для этого, чтобы инициализация по умолчанию была правильно сформирована и не вызывала неопределенного поведения? Ваше первое предложение отвечает на второе. - person Nicol Bolas   schedule 26.06.2020