将成员函数 ptr 插入映射
inserting member function ptr into a map
编辑 从代码本身删除格式(粗体)。
编辑 2 在答案末尾添加了修复程序
我有以下代码,我试图在其中创建静态多态性和模板 类,
我正在尝试将派生类型成员函数 ptr 中的 只有一个 插入到映射中。
地图的定义是这样的:
std::map<std::string,void(derived::*)()> m_func;
插入命令是这样的:
`m_func.insert(make_pair("yaodav",&derived::HelloWorld));`
这是完整的代码:
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <any>
#include <typeinfo>
#include <typeindex>
using namespace std;
template<class Derived>
class base
{
public:
void clean()
{
cout << "I'm cleannig \n";
}
void process()
{
static_cast<Derived*>(this)->setup();
static_cast<Derived*>(this)->run();
static_cast<Derived*>(this)->cleanup();
}
};
class derived : public base<derived>
{
friend class base<derived>;
void setup() {
m_func.insert(make_pair("yaodav",&derived::HelloWorld));
cout << "derived setup \n"; }
void run() { cout << "derived run \n"; }
void cleanup() { cout << "derived cleanup \n"; }
void HelloWorld() {cout << "hwllo from derived \n"; }
std::map<std::string,void(derived::*)()> m_func;
};
class derived1 : public base<derived1>
{
friend class base<derived1>;
void setup() {cout << "derived1 setup \n"; }
void run() { cout << "derived1 run \n"; }
void cleanup() { cout << "derived1 cleanup \n"; }
void HelloWorld(){}
};
template <class T>
class Y{
public:
std::vector<std::any> m_vec;
};
template <typename T>
class D:public Y<T>
{
public:
friend class Y<T>;
void print()
{
for(auto& e: Y<T>::m_vec)
{
if(e.type()==typeid(base<derived1>*))
{
try {
auto* r = any_cast<base<derived1>*>(e);
r->process();
}
catch(const std::bad_any_cast& e) {
std::cout << e.what() << '\n';
}
}
else
{
try {
auto *r = any_cast<base<derived> *>(e);
r->process();
}
catch(const std::bad_any_cast& e) {
std::cout << e.what() << '\n';
}
}
}
}
};
int main()
{
base<derived>* b = new base<derived>;
base<derived1>* c = new base<derived1>;
D<derived> y;
y.m_vec.push_back(b);
y.m_vec.push_back(c);
y.print();
}
但是当调用插入函数(粗体部分)时,我遇到了分段错误,就像 m_func 不存在一样,而我是 运行 调试器,我不会打印 m_func 我得到:
here is no member or method named m_func
为什么会发生这种情况以及如何解决
修正
base<derived>* b = new derived;
base<derived1>* c = new derived1;
而不是
base<derived>* b = new base<derived>;
base<derived1>* c = new <derived1>;
您的代码大致等同于:
base<derived>* b = new base<derived>;
b->process();
在process
里面,有static_cast<Derived*>(this)
——但是b
指向的base<derived>
的实例实际上是而不是 derived
的实例。您已独立实例化 base<derived>
,而不是 derived
实例的一部分。您的程序从未创建 derived
的实例,也没有创建 derived1
的实例。所以你试图调用一个从未存在过的对象的成员函数,于是你的程序表现出未定义的行为。
更精简的代码版本如下所示:
class Base{};
class Derived : public Base {
public:
void DoSomething() {};
};
int main() {
Base* b = new Base;
static_cast<Derived*>(b)->DoSomethind(); // undefined behavior here
}
这样应该更清楚哪里出了问题
编辑 从代码本身删除格式(粗体)。
编辑 2 在答案末尾添加了修复程序
我有以下代码,我试图在其中创建静态多态性和模板 类, 我正在尝试将派生类型成员函数 ptr 中的 只有一个 插入到映射中。 地图的定义是这样的:
std::map<std::string,void(derived::*)()> m_func;
插入命令是这样的:
`m_func.insert(make_pair("yaodav",&derived::HelloWorld));`
这是完整的代码:
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <any>
#include <typeinfo>
#include <typeindex>
using namespace std;
template<class Derived>
class base
{
public:
void clean()
{
cout << "I'm cleannig \n";
}
void process()
{
static_cast<Derived*>(this)->setup();
static_cast<Derived*>(this)->run();
static_cast<Derived*>(this)->cleanup();
}
};
class derived : public base<derived>
{
friend class base<derived>;
void setup() {
m_func.insert(make_pair("yaodav",&derived::HelloWorld));
cout << "derived setup \n"; }
void run() { cout << "derived run \n"; }
void cleanup() { cout << "derived cleanup \n"; }
void HelloWorld() {cout << "hwllo from derived \n"; }
std::map<std::string,void(derived::*)()> m_func;
};
class derived1 : public base<derived1>
{
friend class base<derived1>;
void setup() {cout << "derived1 setup \n"; }
void run() { cout << "derived1 run \n"; }
void cleanup() { cout << "derived1 cleanup \n"; }
void HelloWorld(){}
};
template <class T>
class Y{
public:
std::vector<std::any> m_vec;
};
template <typename T>
class D:public Y<T>
{
public:
friend class Y<T>;
void print()
{
for(auto& e: Y<T>::m_vec)
{
if(e.type()==typeid(base<derived1>*))
{
try {
auto* r = any_cast<base<derived1>*>(e);
r->process();
}
catch(const std::bad_any_cast& e) {
std::cout << e.what() << '\n';
}
}
else
{
try {
auto *r = any_cast<base<derived> *>(e);
r->process();
}
catch(const std::bad_any_cast& e) {
std::cout << e.what() << '\n';
}
}
}
}
};
int main()
{
base<derived>* b = new base<derived>;
base<derived1>* c = new base<derived1>;
D<derived> y;
y.m_vec.push_back(b);
y.m_vec.push_back(c);
y.print();
}
但是当调用插入函数(粗体部分)时,我遇到了分段错误,就像 m_func 不存在一样,而我是 运行 调试器,我不会打印 m_func 我得到:
here is no member or method named m_func
为什么会发生这种情况以及如何解决
修正
base<derived>* b = new derived;
base<derived1>* c = new derived1;
而不是
base<derived>* b = new base<derived>;
base<derived1>* c = new <derived1>;
您的代码大致等同于:
base<derived>* b = new base<derived>;
b->process();
在process
里面,有static_cast<Derived*>(this)
——但是b
指向的base<derived>
的实例实际上是而不是 derived
的实例。您已独立实例化 base<derived>
,而不是 derived
实例的一部分。您的程序从未创建 derived
的实例,也没有创建 derived1
的实例。所以你试图调用一个从未存在过的对象的成员函数,于是你的程序表现出未定义的行为。
更精简的代码版本如下所示:
class Base{};
class Derived : public Base {
public:
void DoSomething() {};
};
int main() {
Base* b = new Base;
static_cast<Derived*>(b)->DoSomethind(); // undefined behavior here
}
这样应该更清楚哪里出了问题