问题
Consider the following non class template that has a template variable and uses template aliasing and auto type deduction.
template<typename T>
using Type = T;
using TypeA = Type<int>;
using TypeB = Type<double>;
class Foo {
private:
template<typename T>
static Type<T> type_;
public:
template<typename T>
explicit Foo( Type<T> type ) { type_<T> = type; }
// non static member
template<typename T>
auto bar() { return type_<T>; }
// static member
template<typename T>
static auto bar(T _x_ = 0) { return type_<T>; }
};
And the program that uses it:
// has to be defined in some cpp file.
template<typename T>
Type<T> Foo::type_;
int main() {
TypeA a{ 7 };
TypeB b{ 3.41 };
Foo f1( a );
Foo f2( b );
auto x = Foo::bar<TypeA>();
auto y = Foo::bar<TypeB>();
std::cout << "static auto f1: " << x << '\n';
std::cout << "static auto f2: " << y << '\n';
std::cout << "member f1: " << f1.bar<TypeA>() << '\n';
std::cout << "member f2: " << f2.bar<TypeB>() << '\n';
return 0;
};
Output
static auto f1: 7
static auto f2: 3.41
member f1: 7
member f2: 3.41
In the class declaration; I'm using a parameter T
in the static version and defaulting it to 0 so that this can be called without any parameters. If this is not added then one would not be able to overload a static and a non static member function that has no arguments or the same arguments for its parameter list.
Would this be considered a quick fix or a hack, or is this a possible way to be able to provide the same type of interface for both a static and non static member function with the same name and functionality?
The function argument or parameter is a dummy argument as does absolutely nothing to the internal value.
After coming back and reading this again I can see were some of the confusion was coming from and I left out the facts that this pertains more to the use of variable templates and being able to access them.
So I think the real question should of been: Concerning variable template members and that they are required to be static, what is the preferred way to access them through a member function: via static or non static, or is there no preference and that choice is left up to the programmer?
One other last thing; are there any unforeseen issues that may lead to future consequences with this type of design pattern - interface?
回答1:
Is this considered a quick fix or a hack, or is this the proper way to be able to provide the same type of interface for both a static and non static member function of the same name?
There is no proper way to accomplish an improper goal. Besides which, your version does not provide the same interface. The non-static version requires an explicit template argument, whereas the static version can use deduction, as in f1.bar(1)
. I'm not sure I'd recommend using the deduction in this case (because the code is more cryptic), but the possibility is provided. Your improper goal is not even met.
If the functions have the same functionally (as in your example), then the non-static version is pointless overhead. Provide just the static version, and if someone wants to call it from an object, that's A-OK.
If the functions do not have the same functionally (maybe your example was oversimplified?), then giving them the same name is a Bad Idea. This includes the case where the non-static version can return different values depending on *this
. At the very least in this case, the static version should be renamed to something like bar_no_object()
to distinguish it from the version that depends on the object.
One other last thing; are there any unforeseen issues that may lead to future consequences with this type of design pattern - interface?
Well, basically you are setting yourself up for a load of confusion. Everyone else will expect Foo::bar()
and Foo{}.bar()
to invoke the same (static) function, and you are trying to break that.
Pay attention to your compiler's messages. This expectation of everyone else is the reason you were not able "to overload a static and a non static member function that has no arguments or the same arguments for its parameter list." You tried to create ambiguity and the compiler stopped you. With good reason. Before asking if your workaround is valid, perhaps you should have asked for the reason the compiler stopped you?
来源:https://stackoverflow.com/questions/57128945/is-this-an-elegant-way-to-overload-a-static-member-function-that-provides-the-sa