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

时间:2022-07-28 16:09:22

What's the proper way to declare the coord variable in the example below? A template argument placeholder will work such as:

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

MyClass<int>::Coord coord;

That sure is ugly considering that Coord is completely agnostic of the template argument. Ideally, is there some syntax that would allow me to declare coord without specifying any template parameter?

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

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

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

3 个解决方案

#1


1  

If you want to be able to use Coord without a template type for MyClass, move it (and all the non-template stuff) from MyClass to a non-template base class. You'll be using it as:

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

MyBase::Coord coord;

and you'll get the following to equal to true:

你会得到以下等于真:

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

I don't know a case where you'd want it to be false for an enum, unless you want to specialize it.

我不知道你想要一个枚举的假的情况,除非你想专门化它。

#2


1  

Consider:

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

What I hope to show you with this example is that specifying the template parameter actually can make a huge difference, even if Coord itself does not depend on it. Thus, if Coord really shouldn't depend on the template parameter (which seems to be the case here), then it shouldn't be a member of the template class in the first place.

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

#3


1  

Basically adding to what everyone else said, you should consider if it should be a class member at all, and if it should be, you should consider moving it to a base class.

基本上添加到其他人所说的内容,你应该考虑它是否应该是一个类成员,如果它应该是,你应该考虑将它移动到基类。

Having said that, you can create the following code, which, while somewhat convoluted, will allow you to use

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

MyClass<>::Coord coord;

Start by defining a dummy class in a detail namespace:

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

namespace detail
{
    struct MyClassVoid{};
};

Now declare your class

现在宣布你的班级

template <typename T>
class MyClass;

and give it a specialization to the dummy class, in which you define the "non template" stuff:

并给它一个专门化的虚拟类,在其中定义“非模板”的东西:

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

Now define the general form of the class, deriving from the specialized one:

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

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

This will build:

这将构建:

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

Full code:

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

#1


1  

If you want to be able to use Coord without a template type for MyClass, move it (and all the non-template stuff) from MyClass to a non-template base class. You'll be using it as:

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

MyBase::Coord coord;

and you'll get the following to equal to true:

你会得到以下等于真:

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

I don't know a case where you'd want it to be false for an enum, unless you want to specialize it.

我不知道你想要一个枚举的假的情况,除非你想专门化它。

#2


1  

Consider:

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

What I hope to show you with this example is that specifying the template parameter actually can make a huge difference, even if Coord itself does not depend on it. Thus, if Coord really shouldn't depend on the template parameter (which seems to be the case here), then it shouldn't be a member of the template class in the first place.

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

#3


1  

Basically adding to what everyone else said, you should consider if it should be a class member at all, and if it should be, you should consider moving it to a base class.

基本上添加到其他人所说的内容,你应该考虑它是否应该是一个类成员,如果它应该是,你应该考虑将它移动到基类。

Having said that, you can create the following code, which, while somewhat convoluted, will allow you to use

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

MyClass<>::Coord coord;

Start by defining a dummy class in a detail namespace:

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

namespace detail
{
    struct MyClassVoid{};
};

Now declare your class

现在宣布你的班级

template <typename T>
class MyClass;

and give it a specialization to the dummy class, in which you define the "non template" stuff:

并给它一个专门化的虚拟类,在其中定义“非模板”的东西:

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

Now define the general form of the class, deriving from the specialized one:

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

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

This will build:

这将构建:

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

Full code:

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