In one of my projects, I'm getting the error "the associated constraints are not satisfied" for one of my C 20 concepts. It appears to me that my code is correct, so I must misunderstand something about the language.
I have rewritten the code to remove all of the obviously extraneous details.
Here are the include statements:
#include <array>
#include <memory>
The constraint I'm defining is on the member function Afunc
below:
template<typename BLikeType>
class A {
public:
A(std::shared_ptr<C> c_) : c_(std::move(c_)) {}
template<typename... Args>
requires requires (BLikeType t, Args... args) {
{t.Bfunc(c_->Cfunc(args...))};
}
std::array<double, sizeof...(Args)> Afunc(Args... args) {
return c_->Cfunc(args...);
}
private:
std::shared_ptr<C> c_;
};
The classes B
and C
were written in a way to try to satisfy the constraint above. I use an std::array<double, 2>
only so that readers understand that the variadic template in A
is necessary.
class C {
public:
C() {}
std::array<double, 2> Cfunc(double a, double b) {
return { a, b };
}
};
I have also written a class B
for the template parameter BLikeType
in A
. It is given below:
class B {
public:
B(){}
double Bfunc(std::array<double, 2> my_array) {
return my_array[0] my_array[1];
}
};
I then try to test this constraint in my main function:
int main() {
C c{};
std::shared_ptr<C> c_ptr = std::make_shared<C>(c);
A<B> a(c_ptr);
std::array<double, 2> answer = a.Afunc<double, double>(.1, .2); // Error: the associated constraints are not satisfied
return 0;
}
Why does this give the error that my constraint is not satisfied?
CodePudding user response:
template<typename... Args>
requires requires (BLikeType t, Args... args) {
{t.Bfunc(c_->Cfunc(args...))};
}
std::array<double, sizeof...(Args)> Afunc(Args... args) {
return c_->Cfunc(args...);
}
The requires-clause is not a complete-class context, so it can't see later-declared class members like c_
. You can move the declaration of c_
earlier in the class, but even then it won't see it with any necessary cv-qualification if the function is const
(since the function declarator isn't seen at that point). Using a trailing requires-clause can solve that issue. In this case there's no extra cv-qualification to add, though, so it doesn't really matter.