【问题标题】:Template specialization alias模板专业化别名
【发布时间】:2012-05-03 20:28:51
【问题描述】:

我最近遇到了一个问题。我实际上认为它无法像我希望的那样解决,但如果可以的话,它会非常方便。无论如何,这是问题所在:

我会给你一个我几天前在这个论坛上看到的例子,因为它会更容易解释。假设我正在尝试以这种方式创建张量结构:

template <int N>
struct Tensor
{
    Tensor<N - 1> x;
    Tensor<N - 1> y;
    Tensor<N - 1> z;
};

为了避免无限递归,我必须为 N = 1 编写模板特化。

template<>
struct Tensor<1>
{
    double x;
    double y;
    double z;
};

其实,当N=1时,这个Tensor其实就是一个Vector(物理的)。假设我已经以这种方式定义了一个 Vector 结构:

struct Vector
{
    double x;
    double y;
    double z;
};

这个结构和 Tensor 完全一样。由于 Vector 结构已经存在,假设我自己没有实现它,我希望能够使 Tensor 结构成为 Vector 结构的别名。就像 typedef 一样。所以,我想这样做:

// C++03
typedef Vector Tensor<1>;

// or C++11
using Tensor<1> = Vector;

这样一来,Tensor 和 Vector 将是完全相同的结构,因此我可以在程序中的任何地方使用一个而不是另一个,而我不必编写相同的结构两次。

但是,实际上不可能以这种方式定义模板特化。如果是的话,我就不会在那里问这个问题了。

注意:我知道前面的例子不是一个好例子,因为我们仍然可以这样做:

using Vector = Tensor<1>;

但如果我想用两个不同结构的特化来做这件事,那就太麻烦了。例如,在编写可以在 N 维空间中计算几何的几何库时:

using Circle<2> = Hypersphere<2>;

所以,总结一下:有没有办法通过将模板特化定义为另一个模板的别名来创建它?

【问题讨论】:

    标签: c++ templates c++11 template-specialization


    【解决方案1】:

    鉴于遗留类 Scalar、Vector 和 Matrix,您可以使用继承:

    template<>
    class Tensor<0>: public Scalar {};
    
    template<>
    class Tensor<1>: public Vector {};
    
    template<>
    class Tensor<2>: public Matrix {};
    

    请注意,这不是滥用继承,因为您正在建模 is-a 关系。

    【讨论】:

    • 是的,我已经想到了,但如果我这样做了,这些课程就不会“完全一样”了。我的意思是我必须强制转换和 down_cast 才能将变量从一种类型传递到另一种类型:/ 我知道这只是一个细节,也许以我的方式思考这些类不被认为是类型安全的,但这正是我的细节想克服。无论如何谢谢:)
    • @Morwenn 为了更通用,您的示例需要两个模板参数:`template class Tensor。在这里,D 是空间维度的数量。
    • 是的,但我只是展示这个例子只是为了暴露一个语法问题。我自己不使用张量或任何东西。这只是为了清除我对 C++ 可能性的想法^^"
    • @Morwenn 您不必担心转换:您可以简单地传递一个 Tensor ,因为没有切片(这是简单的 Liskov-substition)。只要 Vector 具有复制构造函数,您就可以避免反方向转换。 (即只需编写一个使用 Vector 复制构造函数的 Tensor::Tensor(const Vector&) 构造函数。)
    • 是的,没错。它不像我想要的那样“美丽”,因为无论如何这将是两个不同的类,但你仍然可以很容易地使用它。谢谢大家:)
    猜你喜欢
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多