Я пытаюсь реализовать что-то вроде Haskell Prelude в C ++ с помощью классов типов, таких как Functor, Monoid и так далее.Поэтому я решил использовать C ++ Concepts для проверки типов, но столкнулся с проблемой при попытке реализовать концепцию полугруппы.
Проблема возникает, когда я пытаюсь объявить концепцию, которая использует некоторую объявленную функциюи перегружен для необходимых типов позже в коде, но это актуально только для некоторых типов, таких как std :: vector, но для моих собственных типов работает хорошо.
Полный код:
template<class T>
struct S {
// ...
};
template<class T>
concept Addable = requires(T a, T b) {
{ add(a, b) } -> T;
};
template<class T>
S<T> add(const S<T> & a, const S<T> & b) {
// ...
return {};
}
template<class T>
std::vector<T> add(const std::vector<T> & a, const std::vector<T> & b) {
// ...
return {};
}
int main() {
std::cout << Addable<S<int>> << '\n';
std::cout << Addable<std::vector<int>> << '\n';
}
Iожидаем вывод 1 1
, но фактический вывод 1 0
.Таким образом, он не распознает std :: vector как Addable независимо от объявленной перегрузки add (std :: vector), но распознает тип S как Addable.
UPD: Проблема исчезнет, если я переместу функцию add
, чтобы перейти к концепции Addable
.Но выглядит очень неудобно и неясно, что мне нужно реализовать все концепции, которые я включаю, для таких типов, как std::vector
, прежде чем включать эти концепции.
UPD2: Я использую GCC 9.1.0.