基本上我有以下课程:
class StateMachine {
...
StateMethod stateA();
StateMethod stateB();
...
};
Run Code Online (Sandbox Code Playgroud)
stateA()和stateB()方法应该能够返回指向stateA()和stateB()的指针.如何输入定义StateMethod?
我创建了一个Timer类,当计时器到期时必须调用一个回调方法.目前我使用普通函数指针(它们被声明为void(*)(void),当Elapsed事件发生时,函数指针被调用.
是否可以使用也具有签名void(AnyClass ::*)(void)的成员函数执行相同的操作?
谢谢你的队友.
编辑:此代码必须在Windows上以及在实时操作系统(VxWorks)上工作,因此不使用外部库会很棒.
EDIT2:只是为了确定,我需要的是有一个Timer类,它在构造函数中接受一个参数,不带参数,然后返回void的"AnyClass.AnyMethod".我必须存储这个参数,后者在代码中只执行此变量指向的方法.希望很清楚.
我有另外一个与安全bool成语有关的问题:
typedef void (Testable::*bool_type)() const; // const necessary?
void this_type_does_not_support_comparisons() const {} // const necessary?
operator bool_type() const
{
return ok_ ? &Testable::this_type_does_not_support_comparisons : 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么在bool_type(typedef的),并this_type_does_not_support_comparisons有const?无论如何,没有人应该通过返回指针实际调用成员函数,对吧?这const有必要吗?会operator bool_type(成员函数)违反常量,正确性,否则?
c++ const member-function-pointers const-correctness safe-bool-idiom
我试图使用std :: bind()来创建一个函数,该函数将调用虚函数的基类版本,而不是调用派生类的版本.
struct Base
{
virtual void foo() { cout << "Base\n"; }
};
struct Derived : public Base
{
virtual void foo() { cout << "Derived\n"; }
};
int main(int argc, const char * argv[])
{
Base* base = new Derived;
auto baseMethodHopefully = std::bind( &Base::foo, base );
baseMethodHopefully(); // Want call to Base::foo(), but get call to Derived::foo().
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我从其他地方了解到你通常不能以"反虚拟"方式调用基本功能,例如这样.一个明显的例外是常见的范例:
void Derived::bar() { Base::bar(); }
Run Code Online (Sandbox Code Playgroud)
由于表达Base::bar()被认定为"反虚"(在这个意义上,我暗指)派生的方法中,是可以绑定到Base::bar()从希望的方式内源性的方法之一?例如:
void …Run Code Online (Sandbox Code Playgroud) 将指向成员函数的指针转换为使用同一类的另一个指向成员函数的函数是否合法reinterpret_cast?以下示例有效.但这是合法的吗?
#include<iostream>
#include<vector>
#include<string>
class A
{
public:
void func_int(int x) { std::cout << x << std::endl; }
void func_string(std::string const& x) { std::cout << x << std::endl; }
};
int main()
{
std::vector<void(A::*)()> v;
v.push_back(reinterpret_cast<void(A::*)()>(&A::func_int));
v.push_back(reinterpret_cast<void(A::*)()>(&A::func_string));
A a;
(a.*reinterpret_cast<void(A::*)(int)>(v[0]))(5);
(a.*reinterpret_cast<void(A::*)(std::string const&)>(v[1]))(std::string{"Test"});
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有以下代码:
#include <functional>
struct X {
int get() const& {
return 42;
}
};
template<typename Func>
std::result_of_t<Func(X)> Apply(Func fn) {
X x;
return fn(x);
}
int main(void) {
Apply([](X const& x){return x.get();});
//Apply(std::mem_fn(&X::get)); // does not compile
}
Run Code Online (Sandbox Code Playgroud)
第一次调用Apply编译很好,但如果我取消注释第二次调用,我得到以下编译错误:
main.cpp:16:5: error: no matching function for call to 'Apply'
Apply(std::mem_fn(&X::get)); // does not compile
^~~~~
main.cpp:10:27: note: candidate template ignored: substitution failure [with Func = std::_Mem_fn<int (X::*)() const &>]: no type named 'type' in 'std::result_of<std::_Mem_fn<int (X::*)() const &> (X)>' …Run Code Online (Sandbox Code Playgroud) 尝试创建int到成员函数指针的映射,并在构造函数初始值设定项中初始化它.像这样:
class X
{
using STATEFUNC = void(X::*)(int);
public:
X() : m{ { 1, &setState1 } } {}
void setState1(int x) { cout << "state1" << endl; }
void setState2(int x) { cout << "state2" << endl; }
std::map<int, STATEFUNC> m;
};
Run Code Online (Sandbox Code Playgroud)
我会说这是正确的,但Visual Studio 2017说:
错误C2664'std :: map,std :: allocator >> :: map(std :: initializer_list>)':无法将参数1从'initializer list'转换为'std :: initializer_list>'
错误C2276'&':对绑定成员函数表达式的非法操作
从成员函数中删除运算符的地址时,第一条错误消息保持不变,但第二条错误消息更改为:
错误C3867'X :: setState1':非标准语法; 使用'&'创建指向成员的指针
如何在构造函数初始化列表中初始化int到成员函数指针的映射?
是否有一些库允许我在c ++中轻松方便地创建面向对象的回调?
例如,埃菲尔的语言具有"代理人"的概念,其或多或少的工作方式如下:
class Foo{
public:
Bar* bar;
Foo(){
bar = new Bar();
bar->publisher.extend(agent say(?,"Hi from Foo!", ?));
bar->invokeCallback();
}
say(string strA, string strB, int number){
print(strA + " " + strB + " " + number.out);
}
}
class Bar{
public:
ActionSequence<string, int> publisher;
Bar(){}
invokeCallback(){
publisher.call("Hi from Bar!", 3);
}
}
Run Code Online (Sandbox Code Playgroud)
输出将是:嗨来自Bar!3来自Foo!
所以 - 代理允许将成员函数封装到一个对象中,沿着一些预定义的调用参数(来自Foo的Hi)给它,指定打开的参数(?),然后将它传递给其他对象,然后再调用它.
由于C++不允许创建非静态成员函数的函数指针,似乎并不容易实现容易在C++使用的东西.我在c ++中找到了一些关于面向对象回调的谷歌的文章,但是,实际上我正在寻找一些我可以导入的库或头文件,它允许我使用一些类似优雅的语法.
有人给我一些提示吗?
谢谢!
与虚拟成员函数相反,我需要一种解决方案,其中可以注册在每个级别类派生中实现的函数,以便稍后由基类调用.(不仅仅是最衍生的实现)
为此,我正在考虑为派生类提供一种机制,以便在基类中注册它们的函数,例如在派生类构造函数中.
我遇到了成员函数指针参数的问题.我以为Derived是从Base派生的,this指针应该自动生成.
这可以接近我正在尝试或我需要使用静态成员函数void *,和static_cast?
class Base
{
protected:
typedef void (Base::*PrepFn)( int n );
void registerPrepFn( PrepFn fn ) {};
}
class Derived : public Base
{
Derived() {
registerPrepFn( &Derived::derivedPrepFn );
};
void derivedPrepFn( int n ) {};
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
error: no matching function for call to 'Derived::registerPrepFn(void (Derived::*)(int))'
note: candidates are: 'void Base::registerPrepFn(void (Base::*)(int))'
Run Code Online (Sandbox Code Playgroud) 考虑这个特殊的容器类,它存储包含键和值的类型,所以
template<typename K, typename T, K (T::*method)() const>
class Container
{
//...
};
Run Code Online (Sandbox Code Playgroud)
K是键的类型,T是一种值,方法指针用于从值中检索键.
它工作正常,但我想包含方法指针的默认值,以便当调用者没有指定它时,它将是operator K() const这样的:
template<typename K, typename T, K (T::*method)() const = &T::operator K const>
Run Code Online (Sandbox Code Playgroud)
但这并没有编译声明no member operator const K on A (<- my class I test this with)当我尝试实例化它时(并且有这样的方法).甚至可以使用方法指针模板参数的默认值吗?如果是,那么正确的语法是什么?
编辑:除了下面的解决方案,还有一个"修复"的情况,当T是一个使用新的C++ 11功能的指针std::remove_pointer<T>::type,所以:
template<typename K, typename T, K (std::remove_pointer<T>::type::*method)() const = &std::remove_pointer<T>::type::operator K>
Run Code Online (Sandbox Code Playgroud)