I have a class A
that is trying to call a nonmember function DoTheThing
. DoTheThing
is a friend of class A
so that it can call a private member function TheThing
of A
. DoTheThing
is a template function so that it can call TheThing
in multiple user-defined classes. Because the error references an overloaded function, I believe that I am redefining DoTheThing
within A
, but I cannot figure out how to fix this error.
#include <iostream>
#include <vector>
template<typename Component>
requires requires (std::vector<double>& vec, int i) {Component::TheThing(vec, i); }
static void DoTheThing(std::vector<double>& vec, int i) {
Component::TheThing(vec, i);
}
class A {
template<class Component>
friend void DoTheThing(std::vector<double>& vec, int i);
public:
A() {
vec_.resize(10, 5);
DoTheThing<A>(vec_, 7); // Error: no instance of overloaded function
}
private:
static void TheThing(std::vector<double>& vec, int i) {
vec[i] = vec[i] * i;
}
std::vector<double> vec_;
};
Am I redefining DoTheThing
? How do I make the non-member DoTheThing
a friend of A
? How do I call DoTheThing
in the constructor of A
?
You are not constraining the friend
declaration with an ad-hoc requires clause, so you are actually not granting friendship to the same DoTheThing
function you want. You need to replicate the requires
clause in the friend
declaration as well:
class A {
template<class Component>
requires requires (std::vector<double>& vec, int i) {Component::TheThing(vec, i); }
friend void DoTheThing(std::vector<double>& vec, int i);
// ...
};
Here's a demo.
However, you should name this concept, and the usage will be simpler:
template<typename Component>
concept CanDoThing = requires (std::vector<double>& vec, int i) {
Component::TheThing(vec, i);
};
template<CanDoThing Component>
static void DoTheThing(std::vector<double>& vec, int i) {
Component::TheThing(vec, i);
}
class A {
template<CanDoThing Component>
friend void DoTheThing(std::vector<double>& vec, int i);
// ...
};