重构多个重复的函数,只在最内层作用域不同
Refactor multiple repeated functions differing only at the innermost scope
我正试图找到一个重构解决方案以下场景。我有许多重复的函数,每个都做完全相同的事情,除了在一个类实例上调用不同的成员函数,这个类实例只在最内部作用域中可用。
struct MyObject
{
void Function1() {};
void Function2() {};
void Function3() {};
void Function4() {};
};
std::vector<MyObject *> objects;
void CommandHandler1()
{
if (true) // lots of preconditions
{
size_t id = 0;
if (true) // lots of lookup code for id
{
MyObject *myObject = objects.at(id);
myObject->Function1();
}
// refresh code
}
// cleanup code
}
// another CommandHandler2, CommandHandler3, CommandHandler4, etc. doing the same thing but for a different member function.
我想避免多个CommandHandlerx的重复,因为它们非常相似。我所尝试的是传递std::函数来处理任何实例,因为我不能绑定到特定的实例。对这个问题的回答意味着应该编译下面的小程序。
#include <functional>
void CommandHandler(std::function<void(MyObject *)> func)
{
if (true) // lots of preconditions
{
size_t id = 0;
if (true) // lots of lookup code for id
{
MyObject *myObject = objects.at(id);
func(myObject);
}
}
// cleanup code
}
void MenuHandler(int chosen)
{
switch (chosen)
{
case 0: CommandHandler( &MyObject::Function1); break;
case 1: CommandHandler( &MyObject::Function2); break;
case 2: CommandHandler( &MyObject::Function3); break;
case 3: CommandHandler( &MyObject::Function4); break;
}
}
int main()
{
MyObject *obj1 = new MyObject;
MyObject *obj2 = new MyObject;
objects.push_back(obj1);
objects.push_back(obj2);
MenuHandler(1);
delete obj1; delete obj2;
return 0;
}
不幸的是,这不能构建。我认为,因为我没有绑定特定的this
指针:
C:Program Files (x86)Microsoft Visual Studio12.0VCincludefunction (506): error C2664: 'void std::_Func_class<_Ret,MyObject *>::_Set(std::_Func_base<_Ret,MyObject . sh)*> *)':无法将参数1从'_Myimpl *'转换为'std::_Func_base<_Ret,MyObject *> *'
我的问题是(1)我是否在上面的std::函数尝试中做错了什么,或者(2)是否有任何其他模式可以重构这个场景?
您的代码与GCC一起工作,因此它很可能是MSVC实现std::function
的特性。我将提供一些变通方法。
如果函数1–4真的都遵循相同的签名,你根本不需要std::function
,一个普通的成员函数指针就可以了:
void CommandHandler(void (MyObject::*func)())
{
if (true) // lots of preconditions
{
size_t id = 0;
if (true) // lots of lookup code for id
{
MyObject *myObject = objects.at(id);
(myObject->*func)();
}
}
// cleanup code
}
如果你确实需要一个不透明的可调用对象(例如,因为你绑定了一些参数),你应该能够使用std::mem_fn
为std::function
获得一个合适的初始化器:
void MenuHandler(int chosen)
{
switch (chosen)
{
case 0: CommandHandler( std::mem_fn(&MyObject::Function1)); break;
case 1: CommandHandler( std::mem_fn(&MyObject::Function2)); break;
case 2: CommandHandler( std::mem_fn(&MyObject::Function3)); break;
case 3: CommandHandler( std::mem_fn(&MyObject::Function4)); break;
}
}
相关文章:
- C++quit()函数中可能存在作用域问题
- 全局作用域中函数指针的赋值
- 在类函数中初始化外部作用域变量
- 是同一作用域的函数部分中的函数调用
- 未在此作用域中声明的函数和变量 (C++)
- 在构造函数中输入对象时C++类成员作用域
- 函数未在作用域中声明 / 如何结合使用 header.h、header.cpp 和 main.cpp?
- "变量":函数中函数作用域不允许初始化的自动或寄存器变量'naked'
- 如何从类函数返回指向类作用域数组的指针?
- 局部变量的作用域是块或函数
- 当变量在多个函数作用域中使用时,我应该在类 private 中声明该变量吗?
- 缩短成员函数作用域说明符(嵌套类)(C++)
- 块作用域中的函数指针定义
- 当作用域中出现条件时,如何重置函数中的变量?
- 函数在作用域中定义,但编译器抱怨它超出了作用域
- 在编译时选择全局作用域函数
- 函数和类的作用域有什么区别
- 空的唯一指针在离开作用域时调用析构函数
- 作用域仅限于函数的类变量
- 函数作用域是静态变量还是线程本地变量在C++11中的第一个条目中初始化