“转换”函数参数

时间:2015-03-06 23:56:01

标签: c++ c++11 arguments

我正在编写与库接口的C ++类。该库有许多函数,如下所示:

Library.h

int FunctionA(int deviceNumber, ...);
int FunctionB(int deviceNumber, ...);
int FunctionC(int deviceNumber, ...);
int FunctionD(int deviceNumber, ...);
int FunctionE(int deviceNumber, ...);

我的C ++类的每个实例都有一个永远不会改变的关联deviceNumber,因此我将deviceNumber存储为成员变量,每次调用库函数时,我都将成员传递给函数调用的第一个参数。

这很好,我没有理由改变它的方式。但出于好奇,我想知道C ++是否有任何机制来转换"允许我避免在每次调用中传递相同参数的参数。实现这一目标的显而易见的方法是超载一切。我们说我的班级叫Foo

Foo.cpp中

int Foo::FunctionA(...) {
    // deviceNumber_ is a const member
    return ::FunctionA(deviceNumber_, ...);
}

唯一的问题是这需要为每个函数调用一个方法,因此随着库的增长,如果没有代码生成器,它会变得越来越烦人。

是否有任何通用的方法来提供重载行为而不实际重载函数? C ++中是否有一种机制可以扩展"多个参数的争论?我想象它会是这样的:

// These two calls are equivalent
FunctionA(deviceNumber, ...);
FunctionA(Magic(...));
// Magic() expands the arguments, adding deviceNumber

即使解决方案比单独放置一切更加丑陋和可读性,但我很好奇是否可能。搜索后,可变参数模板似乎是最接近的匹配,但我无法真正地了解如何使用它们来实现这一目标。

3 个答案:

答案 0 :(得分:4)

您可能对通用中继功能感到满意:

Live On Coliru

#include <iostream>

int    foo1(int device_number, const char*) { std::cout << __PRETTY_FUNCTION__ << "\n"; return device_number*42; }
double foo2(int device_number)              { std::cout << __PRETTY_FUNCTION__ << "\n"; return device_number*3.14159; }

struct facade {
    facade(int dn) : device_number(dn) {}

    template <typename F, typename... A>
        auto call(F&& f, A&&... args) const {
            return std::forward<F>(f)(device_number, std::forward<A>(args)...);
        }

  private:
    int device_number;
};

int main() {

    facade dev(2);

    std::cout << dev.call(foo1, "yes ma'am") << "\n";
    std::cout << dev.call(foo2) << "\n";

}

答案 1 :(得分:1)

我可能会选择cpp文件中的marco作为最简单的解决方案(严格来说在cpp文件中)

Variadic模板也可以提供帮助。然而,听起来你正在做一些嵌入式的东西,这可能是一个问题。

另外,我不确定您是否意味着每个FunctionA都过载或者FunctionA只涉及一个功能。

无论如何,如果有多个FunctionAs

,我的模板解决方案将会有所帮助
template<typename... Args>
int Foo::FunctionA(Args&& ...args) {
    return ::FunctionA(deviceNumber_, std::forward<Args>(args)...);
}

答案 2 :(得分:0)

我把伪代码用于C ++类型结构。

Class Prototype可能是以下形式。

class Foo {
    private private_member_of_deviceNumber;
    ....
    int FunctionA(...);
    ....
}

Foo类构造函数会将deviceNumber分配给私有成员变量。

class Foo::Foo(int deviceNumber) { 
    int private_member_of_deviceNumber = deviceNumber;
}

Foo类成员FunctionA(...)将喜欢这种形式。

int Foo::FunctionA(...) {
   return ::FunctionA( private_member_of_deviceNumber , ...);
}

这样怎么样?