使用在模板化 C++ 类中定义的类型声明

use of type declaration defined in a templated c++ class

本文关键字:定义 类型 声明 C++      更新时间:2023-10-16

在下面的示例中声明coord变量的正确方法是什么?模板参数占位符将起作用,例如:

MyClass<int>::Coord coord;

考虑到Coord完全与模板参数无关,这肯定是丑陋的。理想情况下,是否有一些语法允许我在不指定任何模板参数的情况下声明coord

template <typename T>
class MyClass {
 public:
  enum Coord {
    x, y, z,
  };  
};
int main(int argc, char *argv[]) {
  MyClass<???>::Coord coord;
}

如果您希望能够使用没有模板类型的Coord MyClass,请将其(以及所有非模板内容)从MyClass移动到非模板基类。您将将其用作:

MyBase::Coord coord;

你会得到以下内容等于true

std::is_same<MyClass<void>::Coord, MyClass<int>::Coord>::value

我不知道您希望将其false enum的情况,除非您想将其专业化。

考虑:

template <>
class MyClass<std::string> {
 public:
  static int Coord = 42;
};

我希望通过这个例子向您展示的是,指定模板参数实际上可以产生巨大的差异,即使Coord本身不依赖于它。因此,如果Coord真的不应该依赖于模板参数(这里似乎是这种情况),那么它首先不应该是模板类的成员。

基本上,除了其他人所说的之外,你应该考虑它是否应该是一个类成员,如果它应该是,你应该考虑把它移动到基类。

话虽如此,您可以创建以下代码,虽然有些复杂,但允许您使用

MyClass<>::Coord coord;

首先在 detail 命名空间中定义一个虚拟类:

namespace detail
{
    struct MyClassVoid{};
};

现在声明你的类

template <typename T>
class MyClass;

并赋予它虚拟类一个专门的功能,在其中定义"非模板"的东西:

template<>
class MyClass<detail::MyClassVoid>
{
public:
enum Coord {
    x, y, z,
}; 
};

现在定义类的一般形式,从专用形式派生:

template <typename T=detail::MyClassVoid>
class MyClass : public MyClass<detail::MyClassVoid> {
    // "Real members" go here.
};

这将构建:

int main(int argc, char *argv[]) {
MyClass<>::Coord coord;
}

完整代码:

namespace detail                                                                                                                            
{
    struct MyClassVoid{};
};
template <typename T>
class MyClass;

template<>
class MyClass<detail::MyClassVoid>
{
public:
enum Coord {
    x, y, z,
}; 
};

template <typename T=detail::MyClassVoid>
class MyClass : public MyClass<detail::MyClassVoid> {
};

int main(int argc, char *argv[]) {
MyClass<>::Coord coord;
}