在C++中,何时以及如何使用回调函数?
编辑:
我想看一个简单的例子来编写回调函数.
可能重复:
带括号的成员函数的地址出错
在最近的这个问题中,OP遇到了C++语言的一个奇怪的规定,如果该成员函数名称被括起来,则取得成员函数的地址是非法的.例如,此代码是非法的:
struct X {
void foo();
};
int main() {
void (X::* ptr)();
ptr = &(X::foo); // Illegal; must be &X::foo
}
Run Code Online (Sandbox Code Playgroud)
我查了一下,发现这是由于C++ ISO规范的§5.3.1/ 3所致
仅当使用显式&时,才会形成指向成员的指针,并且其操作数是未括在括号中的限定ID [...]
有没有人知道为什么规范有这个规则?它特定于指向成员的指针,所以我怀疑这会解决一些语法歧义,但老实说,我不知道它可能是什么.
当一个成员函数指针返回到该类的一个成员函数中的一个类时,我仍然需要指定该类.我不能简单地拿地址.例如,此代码工作正常:
class Foo {
public:
void func(int param) { cout << param << endl; }
void (Foo::*getPointer())(int) { return &Foo::func; }
};
Run Code Online (Sandbox Code Playgroud)
但如果在getPointer
我尝试简单地做:return &func
我得到这个错误:
prog.cpp:在成员函数'
void (Foo::* Foo::getPointer())(int)
':
prog.cpp:8:43:错误:ISO C++禁止获取非限定或带括号的非静态成员函数的地址,以形成指向成员函数的指针.说'&Foo::func
'[-fpermissive]
void (Foo::*getPointer())(int) { return &func; }
为什么我必须在我所在的上下文中指定类?
c++ methods member-function-pointers function-pointers dereference
以下代码:
struct X
{
void f() {}
void g()
{
auto h = &f;
}
};
Run Code Online (Sandbox Code Playgroud)
结果是:
error: ISO C++ forbids taking the address of an unqualified
or parenthesized non-static member function to form a pointer
to member function. Say ‘&X::f’
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么标准不允许和禁止这样做?作为用户,将它称为不合格会更方便,所以我假设有一些其他的理由(安全性?模糊性?编译器实现的简易性?)?
为什么不能将std::cout
地址作为模板参数传递?或者如果有可能那么如何?
这是我尝试过的:
#include <iostream>
template<std::ostream* stream>
class MyClass
{
public:
void disp(void)
{ (*stream) << "hello"; }
};
int main(void)
{
MyClass<&(std::cout)> MyObj;
MyObj.disp();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误信息clang++ -std=c++11
:
main.cpp:15:11: error: non-type template argument does not refer to any declaration
MyClass<&(std::cout)> MyObj;
^~~~~~~~~~~
main.cpp:6:24: note: template parameter is declared here
template<std::ostream* stream>
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
来自g++ -std=c++11
:
main.cpp: In function ‘int main()’:
main.cpp:15:22: error: template argument 1 is invalid
MyClass<&(std::cout)> MyObj;
^
main.cpp:15:29: …
Run Code Online (Sandbox Code Playgroud) 我正在尝试以下代码:
std::thread t(&(Transmitter::sender), this, some_variables);
Run Code Online (Sandbox Code Playgroud)
其中sender是同一个类的成员函数,从该方法调用上面的行.
我收到警告:
Transmitter.h: In member function 'int Transmitter::transmit_streams(std::vector<std::vector<single_stream_record> >, int, Receiver&)':
Transmitter.h:81:44: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&Transmitter::sender' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)
虽然它编译并运行良好.如何删除此警告.
我的g ++是4.6.3,我用-std = c ++ 0x编译代码.