#include
template
T add(T a, T b)
{ return a + b;}
template
concept addable = requires(T a, T b)
{
{ add(a, b) } -> std::same_as;
};
struct foo{};
static_assert(addable);
static_assert(addable); // Passes?!
int main()
{
add(foo{}, foo{}); // Will not compile
}
Можно ли каким-то образом выполнить оценку добавляемого экземпляра шаблона, чтобы foo больше не отображался добавляемым? Можно ввести ограничение на шаблон add, но я ищу более общий подход:
- Компилятор обнаруживает, что единственный match — это шаблон
- Компилятор пытается создать экземпляр шаблона.
Создание экземпляра завершается неудачно где-то в дереве расширения, и концепция оценивается как ложная.
Поскольку вопрос все еще закрыт, я добавляю свой ответ на вопрос. Редактор может удалить его позже.
Ответ:
Используя вывод типа возвращаемого значения, компилятор (по крайней мере, GCC и clang) создаст экземпляр функция, когда концепция оценивается (она должна это делать, иначе она не сможет узнать тип возвращаемого значения). Таким образом, следующий пример ведет себя так, как ожидалось:
#include
template
auto add(T a, T b)
{ return a + b;}
template
concept addable = requires(T a, T b)
{
{ add(a, b) } -> std::same_as;
};
struct foo{};
static_assert(addable);
static_assert(addable);
: In instantiation of 'auto add(T, T) [with T = foo]':
:10:10: required from here
10 | { add(a, b) } -> std::same_as;
| ~~~^~~~~~
:5:12: error: no match for 'operator+' (operand types are 'foo' and 'foo')
5 | { return a + b;}
| ~~^~~
:16:15: error: static assertion failed
16 | static_assert(addable);
| ^~~~~~~~~~~~
:16:15: note: constraints not satisfied
:8:9: required by the constraints of 'template concept addable'
:8:19: in requirements with 'T a', 'T b' [with T = foo]
:10:10: note: the required expression 'add(a, b)' is invalid, because
10 | { add(a, b) } -> std::same_as;
| ~~~^~~~~~
Compiler returned: 1
Подробнее здесь: https://stackoverflow.com/questions/786 ... -c-concept
Мобильная версия