类中常量函数指针变量初始化失败问题咨询
问题分析与解决
首先贴出你的代码:
class foo1{ friend class foo3; int function1(string); string function2(int); protected: public: }; class foo2:protected foo1{ protected: public: }; class foo3:protected foo2{ public: static constexpr function<string(int)> fptr1=function1; };
核心问题拆解
函数签名完全不匹配
function1的签名是int(string)(接收string参数,返回int),但你定义的fptr1类型是std::function<string(int)>(接收int参数,返回string),参数类型和返回值类型完全颠倒,这是编译器报类型转换错误的直接原因。非静态成员函数不能直接赋值给std::function
function1是foo1的非静态成员函数,它的实际类型是int (foo1::*)(std::string),不是普通的全局/静态函数指针。这类函数必须绑定一个类实例(通过this指针)才能调用,没法直接塞进std::function里当普通函数用。constexpr与std::function的兼容性问题
标准里std::function的构造和赋值大多不支持constexpr(C++20起有限支持,但仅针对普通函数指针,成员函数指针依然不行),所以你用static constexpr修饰fptr1本身就不合理,编译大概率通不过。
修正方案示例
假设你是笔误,function1的实际签名应该是string(int)(和fptr1匹配),可以按以下方式修改:
方案1:绑定类实例(适合固定实例调用场景)
#include <functional> #include <string> using namespace std; class foo1{ friend class foo3; string function1(int) { return "test"; } // 修正签名 string function2(int); protected: public: }; class foo2:protected foo1{ protected: public: }; class foo3:protected foo2{ public: static function<string(int)> fptr1; }; // 类外初始化,绑定foo3实例(foo3继承foo1,自身也是foo1的实例) function<string(int)> foo3::fptr1 = [](int x) { foo3 inst; return inst.function1(x); };
方案2:使用成员函数指针(保留实例灵活性)
如果你想让调用者自己指定实例,可以直接用成员函数指针:
#include <string> using namespace std; class foo1{ friend class foo3; string function1(int) { return "test"; } string function2(int); protected: public: }; class foo2:protected foo1{ protected: public: }; class foo3:protected foo2{ public: // 成员函数指针类型,支持constexpr static constexpr string (foo1::*fptr1)(int) = &foo1::function1; }; // 调用方式示例: // foo3 inst; // (inst.*foo3::fptr1)(123);
关于void*转换的问题
把成员函数指针转成void*属于C++标准未定义行为,因为成员函数指针的内存结构和普通指针可能不同,即使编译通过,运行时必然出错,这种方法绝对不能用。
内容的提问来源于stack exchange,提问作者M.J. Park
相关产品推荐
相关产品推荐

