Примечание: все последующее использует реализацию Concepts TS в GCC 6.1
Допустим, у меня есть концепция Surface
, например:
template <typename T>
concept bool Surface() {
return requires(T& t, point2f p, float radius) {
{ t.move_to(p) };
{ t.line_to(p) };
{ t.arc(p, radius) };
// etc...
};
}
Теперь я хочу определить другую концепцию Drawable
, которая соответствует любому типу с функцией-членом:
template <typename S>
requires Surface<S>()
void draw(S& surface) const;
i.e.
struct triangle {
void draw(Surface& surface) const;
};
static_assert(Drawable<triangle>(), ""); // Should pass
То есть Drawable
- это то, что имеет шаблонную константную функцию-член draw()
, принимающую ссылку lvalue на то, что удовлетворяет требованиям Surface
. Это довольно легко указать словами, но я не могу понять, как это сделать на C ++ с помощью Concepts TS. "Очевидный" синтаксис не работает:
template <typename T>
concept bool Drawable() {
return requires(const T& t, Surface& surface) {
{ t.draw(surface) } -> void;
};
}
ошибка: параметр 'auto' не разрешен в этом контексте
Добавление второго параметра шаблона позволяет компилировать определение концепции, но:
template <typename T, Surface S>
concept bool Drawable() {
return requires(const T& t, S& s) {
{ t.draw(s) };
};
}
static_assert(Drawable<triangle>(), "");
Ошибка вывода / замены аргумента шаблона: не удалось вывести параметр шаблона 'S'
теперь мы можем только проверить, соответствует ли конкретная ‹Drawable
, Surface
> пара концепции Drawable
, что не совсем верно. (Тип D
либо имеет требуемую функцию-член, либо нет: это не зависит от того, какой именно Surface
мы проверяем.)
Я уверен, что можно делать то, что мне нужно, но я не могу разобраться с синтаксисом, и в Интернете пока не так много примеров. Кто-нибудь знает, как написать определение концепции, которое требует, чтобы тип имел ограниченную функцию-член шаблона?