Я использую шаблонный класс «A», который вызывает класс «B».
Фокус в том, что вместо этого использования CRTP (наследование). Я использую владение (композицию).
Он работает БЕЗ КОНЦЕПТОВ, но не работает С КОНЦЕПЦИЯМИ.
Вот код для иллюстрации:
Код: Выделить всё
#include
// =========================================================================
// This is the interface I'm trying to enforce
template
concept HasBar = requires(T t, int x)
{
{ t.bar(x) } -> std::same_as;
};
template // If you change "HasBar" to "typename" it compiles
struct A
{
A(Downstream& downstream) :
downstream_{downstream}
{}
int foo(int x) { return downstream_.bar(x); }
private:
Downstream& downstream_;
};
// =========================================================================
// Not using CRTP
struct B
{
using Upstream = A;
int bar(int x) { return x + 1; }
Upstream upstream_{*this}; // Instead we own the parent
};
// =========================================================================
int main()
{
B b;
return b.upstream_.foo(1);
}
Сообщения об ошибках (которые я пытался устранить, поэтому отображается только соответствующая информация):
- ошибка: ограничения не удовлетворены для шаблона класса «A» [with Downstream = B]
используя Upstream = A; - примечание: поскольку «B» не соответствует шаблону «HasBar»
/>
примечание: поскольку 't.bar(x)' будет недействительным: доступ участника к неполному типу 'B'
ПРИМЕЧАНИЕ. Я видел это: можно ли использовать концепции с идиомой CRTP?
Это означает, что я мог изменить код на следующую, менее красивую форму:
Код: Выделить всё
#include
// =========================================================================
// This is the interface I'm trying to enforce
template
concept HasBar = requires(T t, int x)
{
{ t.bar(x) } -> std::same_as;
};
template // Back to "typename"
struct A
{
A(Downstream& downstream) :
downstream_{downstream}
{
static_assert(HasBar); // Aha!
}
int foo(int x) { return downstream_.bar(x); }
private:
Downstream& downstream_;
};
// =========================================================================
// Not using CRTP
struct B
{
using Upstream = A;
int bar(int x) { return x + 1; }
Upstream upstream_{*this}; // Instead we own the parent
};
// =========================================================================
int main()
{
B b;
return b.upstream_.foo(1);
}
Есть ли какие-либо недостатки в использовании static_assert() вместо указания ограничение в шаблоне?
Спасибо!
Подробнее здесь: https://stackoverflow.com/questions/784 ... tance-to-e