Is this an elegant way to overload a static member function that provides the same interface as a non static member function?

本秂侑毒 提交于 2019-12-11 15:59:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!