Reputation: 618
I'm writing C++ class that interfaces with a library. The library has a bunch of functions that look like the following:
Library.h
int FunctionA(int deviceNumber, ...);
int FunctionB(int deviceNumber, ...);
int FunctionC(int deviceNumber, ...);
int FunctionD(int deviceNumber, ...);
int FunctionE(int deviceNumber, ...);
Each instance of my C++ class has an associated deviceNumber
which never changes, so I have deviceNumber
stored as a member variable, and every time I call a library function, I pass the member in as the function call's first argument.
This is fine, and there's no real reason for me to change the way it is. But out of curiosity, I was wondering if C++ had any mechanism to "transform" arguments that would let me avoid passing the same argument in every call. The obvious way to accomplish this is to overload everything. Let's say my class is called Foo
:
Foo.cpp
int Foo::FunctionA(...) {
// deviceNumber_ is a const member
return ::FunctionA(deviceNumber_, ...);
}
The only problem is that this requires a method for each function call, so as the library grows, it gets more and more annoying without a code generator.
Is there any general way to provide the overloading behaviour without actually overloading the functions? Is there a mechanism in C++ to "expand" an argument into multiple arguments? I'm imagining it would look like:
// These two calls are equivalent
FunctionA(deviceNumber, ...);
FunctionA(Magic(...));
// Magic() expands the arguments, adding deviceNumber
Even if the solution is much uglier and less readable than leaving everything alone, I'm curious if it's possible. After searching around, variadic templates seem to be the closest match, but I can't really wrap my head around how they could be used to accomplish this.
Upvotes: 3
Views: 189
Reputation: 393064
You might be happy with a generic relay function:
#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";
}
Upvotes: 4
Reputation: 1723
I would probably choose a marco in the cpp file as the easiest solution (strictly in the cpp file though)
Variadic templates could help here too. However it sounds like you are doing something embedded and that might be an issue.
Also, I'm not sure if you mean that each FunctionA is overloaded or FunctionA refers to exactly one function.
Anyway, my template solution will help if there are multiple FunctionAs
template<typename... Args>
int Foo::FunctionA(Args&& ...args) {
return ::FunctionA(deviceNumber_, std::forward<Args>(args)...);
}
Upvotes: 1
Reputation: 316
I put pseudo code , for C++ type structure.
Class Prototype might be following forms.
class Foo {
private private_member_of_deviceNumber;
....
int FunctionA(...);
....
}
Foo Class constructor will assign deviceNumber to private member variable.
class Foo::Foo(int deviceNumber) {
int private_member_of_deviceNumber = deviceNumber;
}
Foo Class member FunctionA(...) will like this form.
int Foo::FunctionA(...) {
return ::FunctionA( private_member_of_deviceNumber , ...);
}
How about like this way?
Upvotes: 0