templates - C++ 模板类专门化构造函数

标签 templates c++17 template-specialization

我想创建一个像这样的通用 Vector 类 Vector<int Dimension, typename Type> 。这是我的代码:

template <int Dimension, typename Type>
class Vector
{
public:
  Vector() 
    : _data {} 
  {}
  Vector(const std::array<Type, Dimension>& init)
    : _data {init}
  {}
  ...
protected:
 std::array<Type, Dimension> _data;
};

通过该声明,我可以使用 std::array 初始化我的向量.

Vector<3, float> vec({1.0f, 2.0f, 3.0f});
// or like this
Vector<3, float> vec = {{1.0f, 2.0f, 3.0f}};

但现在我希望我的向量有一个更好的构造函数来处理一些常见的向量类型,如 Vec1、Vec2、Vec3,... 我尝试创建一个递归模板类来为每个模板添加一个额外的构造函数:

template <typename Type>
class Vector<3, Type>
{
public:
  Vector(const Type& x, const Type& y, const Type& z)
    : _data {x, y, z}
  {}
};

但是当我编译我的程序时,我收到了这个错误:

error C3861: '_data': identifier not found

我的问题是:

  • 为什么会发生此错误?
  • 我如何为我的 Vector 的一些通用模板添加额外的构造函数.

PS:抱歉,如果我的英语很难理解🤦‍♀️。

最佳答案

为什么?

这里没有递归。 Vector<3, Type>是一个完全独立的东西,与通用的Vector<Dimension, Type>无关。 。它不包含任何_data或主模板包含的任何其他内容。

如何?

这里不需要递归或专门化,您需要一个转发构造函数。

  template <int Dimension, typename Type>
  class Vector
  {
    public:
      template <typename ... T>
      Vector(T&& ... t) 
        : _data{std::forward<T>(t)...} {}
  
    protected:
      std::array<Type, Dimension> _data;
  };

这是您需要的唯一构造函数。它基本上是说“用任何你可以初始化_data的东西来初始化Vector”。所以你可以:

Vector<4, int> v4(1,2,3,4);
Vector<2, int> v2{1,2};

std::array<float, 3> u3 = {1.0, 2.0, 3.0};
Vector<3, float> v3{u3};

Vector<5, float> v5;

这就是全部吗?

没有。也许您确实需要向 Vector<3,Type> 添加一些功能主模板中不存在。在这种情况下,您可以使用继承。

  • 重命名您的 Vector类模板为VectorBase

  • 创建一个新的 Vector继承自“VectorBase”并使用其构造函数的类模板,仅此而已:

    template <int Dimension, typename Type>
    class Vector : public VectorBase<Dimension, Type> {
       public:
           using VectorBase<Dimension, Type>::VectorBase;
    };
    
  • 现在您可以专注于Vector并向其添加功能。您需要重复using每个专业都有声明,但这并不是太多的样板。

关于templates - C++ 模板类专门化构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73583586/

相关文章:

templates - 在 Golang 服务器中呈现 MIME 类型的 Assets 时出错

继承语句中的 C++ 部分特化?

c++ - 将整数常量映射到类型

c++ - 使用别名的显式模板实例化?

c++ - 在非静态数据成员上使用 SFINAE?

c++ - 使用模板在编译时填充运行时数据

c++ - 在给定命名声明的宏内使用变量声明的类型

c++ - 与 `if constexpr` 一起使用的编译时间消息(在预处理器之后)

c++ - 关于 ints 和 static_assert 的特化

c++ - 关于模板特化和继承的良好实践