c++11 std::thread 和 class 友元函数的交互
Interaction between c++11 std::thread and class friend function
我无法理解编译器错误我正在尝试使用声明为 c++11 std::thread
对象中的 class 友元的函数。我创建了一个小示例来说明我遇到的问题。基本上,当编译器只看到 aa
的 friend
函数原型时,它会在将该函数传递给线程对象时抛出一个未定义的符号错误。我正在使用 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;
}
编译命令:
g++ -o test test.cpp -g -O0 -std=c++11 -lpthread
我收到编译器错误:
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));
在上面,如果我替换行
std::thread t1(aa,std::ref(*this));
和
aa(*this);
这编译得很好。或者,如果我在 A::av
的定义之上添加另一个函数原型声明,例如:
void aa(A &p);
使用线程对象声明可以很好地编译。
那么,当我尝试仅使用友元原型声明线程对象时,为什么编译器会反对?
我意识到在这个简单的例子中我可以将 aa
的声明移到 A::av
的定义之上,但是实际上我想做一些更复杂的事情,我有一个派生的 classB
包含B::av
,而aa
的定义逻辑上放在A
的实现文件中,而class的定义A
] 与 aa
的原型位于包含在 class B
定义中的头文件中。这是编译器错误,还是我声明的方式有问题?
只有一个 in-class 声明,友元函数只能通过依赖于参数的查找使用。要通过名称指定它而不调用它,就像在 av
的定义中所做的那样,您需要事先在全局命名空间中声明它,或者将定义移到更早的位置。
我无法理解编译器错误我正在尝试使用声明为 c++11 std::thread
对象中的 class 友元的函数。我创建了一个小示例来说明我遇到的问题。基本上,当编译器只看到 aa
的 friend
函数原型时,它会在将该函数传递给线程对象时抛出一个未定义的符号错误。我正在使用 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;
}
编译命令:
g++ -o test test.cpp -g -O0 -std=c++11 -lpthread
我收到编译器错误:
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));
在上面,如果我替换行
std::thread t1(aa,std::ref(*this));
和
aa(*this);
这编译得很好。或者,如果我在 A::av
的定义之上添加另一个函数原型声明,例如:
void aa(A &p);
使用线程对象声明可以很好地编译。
那么,当我尝试仅使用友元原型声明线程对象时,为什么编译器会反对?
我意识到在这个简单的例子中我可以将 aa
的声明移到 A::av
的定义之上,但是实际上我想做一些更复杂的事情,我有一个派生的 classB
包含B::av
,而aa
的定义逻辑上放在A
的实现文件中,而class的定义A
] 与 aa
的原型位于包含在 class B
定义中的头文件中。这是编译器错误,还是我声明的方式有问题?
只有一个 in-class 声明,友元函数只能通过依赖于参数的查找使用。要通过名称指定它而不调用它,就像在 av
的定义中所做的那样,您需要事先在全局命名空间中声明它,或者将定义移到更早的位置。