C++:如何让函数接受来自任何命名空间的具有相同类名的对象

C++: How to get function to accept an object with same class name from any namespace?

本文关键字:命名空间 对象 同类 任何 函数 C++      更新时间:2023-10-16

MainClass.h:

namespace Alpha{ enum class Parameters; }
namespace Beta { enum class Parameters; }
MainClass{
public:
  enum class Type{ Type_A, Type_B };
  MainClass(const Type t);
  void DoStuff(const Parameters p);
private:
  void doesStuff(const int p_val);
};

主类.cpp:

/* define values for Alpha::Parameters, Beta::Parameters here or elsewhere, and included */
MainClass::MainClass(const Type t){
  /* not sure how to do this. But essentially by switching based on 't' use either Alpha::Parameters or Beta::Parameters */
}
MainClass::DoStuff(const Parameters p){
  int p_value = static_cast<int>(p);
  doesStuff(p_value);
}

这就是我希望能够做到的。这可能吗?实际上,如果枚举类的行为就像一个具有继承的,那就太好了,但我知道我不能这样做。我尝试重写的次数越多,它就会不断螺旋式上升,直到我实际上只为每种情况编写特定的类(我在示例中不止两个)。但是代码都非常相似,真的。

我也知道另一种选择是允许 DoStuff(const 参数 p) 只是一个 DoStuff(constint p_val) 并在外部进行静态转换......但是我必须在其他地方进行所有静态转换,并且我没有得到枚举类的良好类型检查。

如果不可能,那也没关系...但如果是这样,那就太糟糕了。

你试过模板吗?

class Main {
    template < typename PARAMETERS >
    void DoStuff(const PARAMETERS p) {
        doesStuff(static_cast<int>(p));
    }
}

然后,如有必要,您可以为每种参数类型提供专用化。

我错过了关于确定构造函数中哪个 T 的第一部分。 通常我会使用类模板实现它,如下所示:

#include <iostream>
namespace Alpha{ enum class Parameters { A, B, C }; }
namespace Beta { enum class Parameters { a, b, c }; }
template < typename P >
class MainClass{
public:
    MainClass() { }
    void DoStuff(const P p) {
        int p_value = static_cast< int >(p);
        doesStuff(p_value);
    }
private:
    void doesStuff(const int p_val) {
        std::cout << "DoesStuff " << p_val << std::endl;
    }
};
int main(int argc, const char** argv) {
    MainClass< Alpha::Parameters > alpha;
    alpha.DoStuff(Alpha::Parameters::A);
    alpha.DoStuff(Alpha::Parameters::B);
    alpha.DoStuff(Alpha::Parameters::C);
    MainClass< Beta::Parameters > beta;
    beta.DoStuff(Beta::Parameters::a);
    beta.DoStuff(Beta::Parameters::b);
    beta.DoStuff(Beta::Parameters::c);
    return 0;
}

但是,如果DoStuff是唯一依赖于使用哪些参数的部分,我会使用模板函数。

您可以使用函数重载和最少的函数体代码来实现此目的。

MainClass::DoStuff(Alpha::Parameters p){
    int p_value = static_cast<int>(p);
    doesStuff(p_value);
}
MainClass::DoStuff(Beta::Parameters p){
    int p_value = static_cast<int>(p);
    doesStuff(p_value);
}
MainClass::DoStuff(Etcetera::Parameters p){
    int p_value = static_cast<int>(p);
    doesStuff(p_value);
}

所有实现都将在doesStuff()函数中。

这仍然允许您保留使用不同枚举的现有函数调用。

但是,这种类型检查可能并不像您想象的那么有价值......此代码假定所有枚举将保持相同。如果你只更改其中一个(比如 Beta::P arameter 枚举),它会破坏这段代码,并且你将在没有任何警告的情况下引入一个错误。