c++ - 这是重载提供与非静态成员函数相同接口(interface)的静态成员函数的优雅方法吗?

标签 c++ static overloading c++17 template-variables

考虑以下具有模板变量并使用模板别名和自动类型推导的非类模板。

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>; }
};

以及使用它的程序:

// 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;
};

输出

static auto f1: 7
static auto f2: 3.41
member f1: 7
member f2: 3.41

在类声明中;我在静态版本中使用参数 T 并将其默认为 0,以便可以在没有任何参数的情况下调用它。如果不添加它,那么将无法重载没有参数或参数列表具有相同参数的静态和非静态成员函数。

这会被认为是一种快速修复或 hack,还是能够为具有相同名称和功能的静态和非静态成员函数提供相同类型接口(interface)的可能方法?

函数参数或参数是一个虚拟参数,对内部值绝对没有任何作用。

回来再读一遍后,我发现有些困惑是从哪里来的,我忽略了这更多地与变量模板的使用和访问它们有关的事实。

所以我认为真正的问题应该是:关于变量模板成员并且它们必须是静态的,通过成员函数访问它们的首选方式是什么:通过静态或非静态,或者没有偏好而那个选择留给程序员?

最后一件事;这种类型的设计模式 - 界面是否存在任何可能导致 future 后果的不可预见的问题?

最佳答案

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?

没有正确的方法可以实现不正确的目标。除此之外,您的版本不提供相同的界面。非静态版本需要显式模板参数,而静态版本可以使用推导,如 f1.bar(1) 中所示。我不确定我是否会推荐在这种情况下使用推导(因为代码更神秘),但提供了这种可能性。你不正当的目标甚至都没有实现。

如果函数具有相同的功能(如您的示例),则非静态版本的开销毫无意义。只提供静态版本,如果有人想从对象调用它,那没问题。

如果函数在功能上不相同(也许您的示例过于简单?),那么给它们起相同的名字是个坏主意。这包括非静态版本可以根据 *this 返回不同值的情况。至少在这种情况下,应该将静态版本重命名为类似 bar_no_object() 的名称,以区别于依赖对象的版本。

One other last thing; are there any unforeseen issues that may lead to future consequences with this type of design pattern - interface?

好吧,基本上你是在为一大堆困惑做准备。其他人都希望 Foo::bar()Foo{}.bar() 调用相同的(静态)函数,而您正试图打破它。

注意编译器的消息。其他人的这种期望是您无法“重载没有参数或参数列表具有相同参数的静态和非静态成员函数”的原因。你试图制造歧义,编译器阻止了你。有充分的理由。问前if your workaround is valid ,也许您应该询问编译器阻止您的原因?

关于c++ - 这是重载提供与非静态成员函数相同接口(interface)的静态成员函数的优雅方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57128945/

相关文章:

java - 构造函数重载相同的参数

java - 返回未知类型 Java

c# - 为什么在 c#/c++ dll 互操作期间出现 System.AccessViolationException?

c++ - 如何从 C++ 中的另一个实例访问一个实例的信息?

django - Heroku 部署上的静态文件 Django

c - 当 "char bigchar[ 1u << 31 - 1 ];"工作正常时,为什么我应该使用 malloc()?

typescript :基于输入值(枚举)的函数返回类型

c++ - 成员函数指针c++

c++ - 函数背后的逻辑

c++ - 为什么静态成员函数只有在有返回值的情况下才能在全局范围内调用?