简体   繁体   English

重构唯一函数具有不同参数的位置

[英]Refactoring where unique functions have different arguments

I have a class (acting as a wrapper over a library) with member functions that all follow this pattern: 我有一个类(充当库的包装器),其成员函数都遵循以下模式:

MyObject& MyObject::ObjectFunction(int arg1, std::string arg2)
{
    LibraryObject destination_object;
    libraryFunction(destination_object, arg1, arg2);
    setProp(destination_object);
    ~destination_object;
    return *this;
}

I would like to refactor this so that the repeated steps (create destination object, set property, destroy destination object, return address) can be moved into a function of their own, ideally something like this: 我想对其进行重构,以便可以将重复的步骤(创建目标对象,set属性,销毁目标对象,返回地址)移动到它们自己的函数中,理想情况是这样的:

MyObject& MyObject::genericFunction (uniqueLibraryFunction(Args)) 
{
    LibraryObject destination_object;
    uniqueLibraryFunction(Args);
    setProp(destination_object);
    ~destination_object;
    return *this;        
}

void libraryFunction1(int arg1, std::string arg2) 
{
    genericFunction(libraryFunction1(arg1, arg2));
}

void libraryFunction2(double arg1, int arg2) 
{
    genericFunction(libraryFunction2(arg1, arg2));
}

However I am using a library which has methods that require a destination object to return values to. 但是,我使用的库具有要求目标对象返回值的方法。 I have tried to use variadic arguments but I can't seem to get it working since the library functions take different argument lengths and types. 我尝试使用可变参数,但是由于库函数采用不同的参数长度和类型,因此我似乎无法使其正常工作。 I have also tried to use pointer-to-function-members but couldn't get it working for the same reason (argument lengths and types differ between library functions). 我也尝试过使用指向函数成员的指针,但是由于相同的原因(参数长度和类型在库函数之间不同)而无法使用。

My class code is the following: 我的课程代码如下:

class MyObject 
{
    private:
        LibraryObject prop;
    public:
        getProp();
        setProp(int prop);
}

If I understand the question correctly, then it should be doable with a lambda: 如果我正确理解了这个问题,那么应该可以使用lambda来实现:

template <class F>
MyObject& MyObject::genericFunction(F f) 
{
    LibraryObject destination_object;
    f(destination_object);
    setProp(destination_object);
    return *this;        
}

void MyObject::libraryFunction1(int arg1, std::string arg2) 
{
    genericFunction([=](LibraryObject &o) { libraryFunction1(o, arg1, arg2); });
}

void libraryFunction2(double arg1, int arg2) 
{
    genericFunction([=](LibraryObject &o) { libraryFunction2(o, arg1, arg2); });
}

Alternatively, std::bind will do the same job: 另外, std::bind将执行相同的工作:

void MyObject::libraryFunction1(int arg1, std::string arg2) 
{
  genericFunction(std::bind(libraryFunction1, std::placeholders::_1, arg1, arg2));
}

The template shouldn't be an issue, since if it's private, it could easily be implemented just in the source file where all the calls to it reside. 模板不应该成为问题,因为如果它是私有的,则可以轻松地仅在所有对其进行调用的源文件中实现该模板。 However, if that's not an option for you for whatever reason, you can use std::function<void(LibraryObject&)> instead of F . 但是,如果由于某种原因这不是您的选择,则可以使用std::function<void(LibraryObject&)>代替F

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM