C++ - class 中的函数指针向量

C++ - Vector of function pointers inside class

我正在制作自己的编程语言。我制作了从对象 class 派生的 classes(如 'string' 或 'int)。我正在制作标准类型,如 string 和 int,所以我有一个可以解决的基础(如果有意义的话,用它自己扩展我的语言)。每个标准类型都有 unordered_map 个函数。我很想听听修复 this/another 方法的方法。

当我 运行 程序时,我得到这个我不明白的错误:

C2664: 'std::pair<const _Kty,_Ty>::pair(std::pair<const _Kty,_Ty> &&)': cannot convert argument 2 from '_Ty' to 'const _Ty2 &'

指的是第62行,错误出处:

c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.16.27023\include\xmemory0 line:881

xmemory0 中的代码:

template<class _Objty,
        class... _Types>
        static void construct(_Alloc&, _Objty * const _Ptr, _Types&&... _Args)
        {   // construct _Objty(_Types...) at _Ptr
        ::new (const_cast<void *>(static_cast<const volatile void *>(_Ptr)))
            _Objty(_STD forward<_Types>(_Args)...);
        }

我的代码:

#include <iostream>
#include <unordered_map>
#include <string>
#include <functional>

struct Object;
typedef std::unordered_map<std::string, std::function<Object*(std::string*)>> stdtypefunc_map;

struct Object
{

};

struct StdType : public Object
{
    stdtypefunc_map functions;
};

struct stringtype : public StdType
{
    stringtype()
    {
        functions.emplace("GetValue", &stringtype::GetValue);
    }

    Object* GetValue(std::string args[])
    {
        std::cout << "GetValue()" << std::endl;
    }
};

int main()
{
    stringtype s;
    return 0;
}

在您的代码中,第 62 行是这样的语句:

functions.emplace("GetValue", &stringtype::GetValue);

functions 是一个 std::unordered_map,其 key_typestd::stringmapped_typestd::function<Object*(std::string*)>

emplace() 在映射中构造一个新的 std::unordered_map::value_type,将您指定的值传递给 value_type 的构造函数。在这种情况下,value_type 是一个 std::pair<const std::string, std::function<Object*(std::string*)>>,并且您将 2 个值传递给构造函数 std::pair with.

您看到的错误消息基本上是说编译器无法将 &stringtype::GetValue 转换为 std::function<Object*(std::string*)>。例如,这是一个重现相同故障的简化示例,GCC 给出了一个非常详细的错误消息,解释了它失败的原因(对于 post 这里太大了,所以我只 post相关作品):

https://ideone.com/qVLkQd

#include <iostream>
#include <unordered_map>
#include <string>
#include <functional>

struct Object;
typedef std::unordered_map<std::string, std::function<Object*(std::string*)>> stdtypefunc_map;

struct Object
{

};

struct StdType : public Object
{
    stdtypefunc_map functions;
};

struct stringtype : public StdType
{
    stringtype()
    {
        functions.emplace("GetValue", &stringtype::GetValue);
    }

    Object* GetValue(std::string args[])
    {
        std::cout << "GetValue()" << std::endl;
    }
};

int main()
{
    stringtype s;
    return 0;
}
/usr/include/c++/6/ext/new_allocator.h:120:4: error: no matching function for call to ‘std::pair<const std::__cxx11::basic_string<char>, std::function<Object*(std::__cxx11::basic_string<char>*)> >::pair(const char [9], Object* (stringtype::*)(std::__cxx11::basic_string<char>*))’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
/usr/include/c++/6/ext/new_allocator.h:120:4: note:   cannot convert ‘std::forward<Object* (stringtype::*)(std::__cxx11::basic_string<char>*)>((* & __args#1))’ (type ‘Object* (stringtype::*)(std::__cxx11::basic_string<char>*)’) to type ‘const std::function<Object*(std::__cxx11::basic_string<char>*)>&’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...

这是有道理的。您不能将 非静态 方法的指向成员方法的指针存储到 std::function 中,除非您考虑到它将需要一个对象实例来调用上的方法。例如通过使用 std::bind() 将对象实例与指向成员方法的指针绑定:

using std::placeholders::_1;
functions.emplace("GetValue", std::bind(&stringtype::GetValue, this, _1));

或者,通过使用 lambda 捕获对象:

functions.emplace("GetValue", [this](std::string *args){ return this->GetValue(args); });