Reputation: 573
I'm having trouble understanding a compiler error I'm getting trying to use a function declared as a friend to a class in a c++11 std::thread
object. I've created a small example to show the issue I'm having. Basically, when the compiler has only seen the friend
function prototype of aa
, it throws an undefined symbol error when that function is passed into a thread object. I'm using g++ 4.9.2.
//test.cpp
#include <thread>
class A {
public:
friend void aa(A &p);
void av(void);
};
void A::av() {
std::thread t1(aa,std::ref(*this));
}
void aa(A &p) {
p;
}
int main() {
A ai;
ai.av();
return 0;
}
Compiler command:
g++ -o test test.cpp -g -O0 -std=c++11 -lpthread
I get the compiler error:
test.cpp: In member function ‘void A::av()’:
test.cpp:12:18: error: ‘aa’ was not declared in this scope
std::thread t1(aa,std::ref(*this));
In the above, if I replace the line
std::thread t1(aa,std::ref(*this));
with
aa(*this);
This compiles just fine. Alternatively, if I add another prototype declaration of the function above the definition of A::av
, like:
void aa(A &p);
It compiles fine with the thread object declaration.
So why is the compiler objecting when I try to declare the thread object with only the friend prototype?
I realize in this trivial example I could move the declaration of aa
above the definition of A::av
, however in practice I would like do something more complex where I have a derived class B
containing B::av
, and the definition of aa
is logically placed in the implementation file of A
, while the definition of class A
with the prototype of aa
is located in a header file included in the definition of class B
. So is this a compiler bug, or an issue with the way I've declared something?
Upvotes: 3
Views: 939
Reputation: 254721
With only an in-class declaration, the friend function is only available via argument-dependent lookup. To specify it by name without calling it, as you do in the definition of av
, you'll need to declare it in the global namespace beforehand, or move the definition to an earlier point.
Upvotes: 5