std::function vs 别名函数指针,为什么不能编译

pm1*_*100 3 c++

想要调查std:function.

我有这个结构:

struct InstructionDescription
{
    std::string name;
    word mask;
    word code;
    std::function<void(Cpu*, word)> func;
    word flags;
};
Run Code Online (Sandbox Code Playgroud)

我像这样设置了一个向量

std::vector<InstructionDescription> instructions_{
{
    {"clr",     DD_MASK,        0005000,    &Cpu::Clr},
    {"clrb",    DD_MASK,        0105000,    &Cpu::Clr},
    {"com",     DD_MASK,        0005100,    &Cpu::Com},

.....
Run Code Online (Sandbox Code Playgroud)

工作正常。现在,如果我更改结构以使用函数指针:

using InstrFunc = void(*)(Cpu*, word);
struct InstructionDescription
{
    std::string name;
    word mask;
    word code;
    InstrFunc func;
    word flags;
};
Run Code Online (Sandbox Code Playgroud)

据我所知,这应该是等效的。然而我得到

1>C:\work\pdp\mysim\mysim\instructions.h(60,50): error C2664: 'std::vector<Cpu::InstructionDescription,std::allocator<Cpu::InstructionDescription>>::vector(std::initializer_list<_Ty>,const _Alloc &)': cannot convert argument 1 from 'initializer list' to 'std::initializer_list<_Ty>'
1>        with
1>        [
1>            _Ty=Cpu::InstructionDescription,
1>            _Alloc=std::allocator<Cpu::InstructionDescription>
1>        ]
1>        and
1>        [
1>            _Ty=Cpu::InstructionDescription
1>        ]
1>C:\work\pdp\mysim\mysim\instructions.h(60,50): message : Element '1': no conversion from 'initializer list' to '_Ty'
1>        with
1>        [
1>            _Ty=Cpu::InstructionDescription
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\vector(512,5): message : see declaration of 'std::vector<Cpu::InstructionDescription,std::allocator<Cpu::InstructionDescription>>::vector'
1>Console.cpp
Run Code Online (Sandbox Code Playgroud)

VS2019。VS GUI 还突出显示了 std::vector 行,指出“InstructionDescription”未知且函数名称不可访问(例如 &Cpu::Clr)

所述Cpu类的定义如下:

struct Cpu {
    void Clr(word) {}; 
    void Com(word) {}; 
}; 
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Chr*_*phe 6

std::function是非常方便的:它承认&Cpu::Clr是一个成员函数,它的第一个参数是一个Cpu*

当你使它成为一个函数指针时,这不会像这样工作。您必须使用成员函数指针:

using InstrFunc = void (Cpu::*)(word);
Run Code Online (Sandbox Code Playgroud)

附加信息

这是标准的:std::function通过添加指向类的指针作为第一个参数,很好地处理指向成员函数的指针。当然,当你调用它时,你必须提供额外的参数:

Cpu cpu;  
for (auto& i:instructions_) {
    i.func(&cpu, i.code);   // as simple as that with std::function
}
Run Code Online (Sandbox Code Playgroud)

当您查找指向成员函数的指针时,就不太方便了:

Cpu cpu;  
for (auto& i:instructions) {
    (cpu.*i.func)(i.code); 
}
Run Code Online (Sandbox Code Playgroud)

在线演示(您需要注释/注释掉特定行)