混合部分模板特化和默认模板参数

发布于 2024-12-23 06:31:46 字数 1291 浏览 6 评论 0原文

我想创建一个通用向量类并为一些情况创建专业化。像这样的东西(它不会编译,但希望传达我的意图):

template<int dim, typename T = float>
class Vector
{
public:
    typedef Vector<dim, T> VecType;

    Vector() { /**/ }
    Vector(const VecType& other) { /**/ )
    Vector& operator=(const VecType& other) { /**/ }

    VecType operator+(const VecType& other) { /**/ }    
    VecType operator-(const VecType& other) { /**/ }    
    T operator*(const VecType& other) { /**/ }

private:
    std::array<T, dim> elements;
};

template<int dim, typename T>
class Vector<2>
{
public:
    T x() const { return elements[0]; }
    T y() const { return elements[1]; }
};

template<int dim, typename T>
class Vector<3>
{
public:
    T x() const { return elements[0]; }
    T y() const { return elements[1]; }
    T z() const { return elements[2]; }
};

换句话说,我希望元素的默认类型为 float 并且我希望有 x()< dim = 2 情况的 /code> 和 y() 访问器方法,以及 x()y() 和 z()dim = 3 案例。我对错误消息有点困惑:

vector.h:56:10: 错误:声明“int dim”

vector.h:6:10:错误:阴影模板参数“int dim”

(与 T 相同)。

我怎样才能正确地做到这一点? (如果可能的话)

I would like to create a generic vector class and create specializations for a few cases. Something like this (it does not compile, but hopefully communicates my intentions):

template<int dim, typename T = float>
class Vector
{
public:
    typedef Vector<dim, T> VecType;

    Vector() { /**/ }
    Vector(const VecType& other) { /**/ )
    Vector& operator=(const VecType& other) { /**/ }

    VecType operator+(const VecType& other) { /**/ }    
    VecType operator-(const VecType& other) { /**/ }    
    T operator*(const VecType& other) { /**/ }

private:
    std::array<T, dim> elements;
};

template<int dim, typename T>
class Vector<2>
{
public:
    T x() const { return elements[0]; }
    T y() const { return elements[1]; }
};

template<int dim, typename T>
class Vector<3>
{
public:
    T x() const { return elements[0]; }
    T y() const { return elements[1]; }
    T z() const { return elements[2]; }
};

In other words, I want the default type of the elements to be float and I want to have x() and y() accessor methods for the dim = 2 case, and x(), y() and z() for the dim = 3 case. I'm a little confused by the error messages:

vector.h:56:10: error: declaration of ‘int dim’

vector.h:6:10: error: shadows template parm ‘int dim’

(same for T).

How can I do this correctly? (if it's possible)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

随遇而安 2024-12-30 06:31:46

1.

当部分特化模板时,仅提供实际上是参数的模板参数。由于您已将 dim 固定为 2 或 3,因此无需再次指定它。

template<typename T>
class Vector<2, T>
{
   ....

2.

专门化一个类实际上意味着更改整个声明。因此,通用 Vector 的成员在专用 Vector<2, T> 中不可用。您可以将通用 Vector 作为内部基类,并创建一个子类以进行专门化:

template<int dim, typename T>
class VectorImpl;

...

template<int dim, typename T = float>
class Vector : public VectorImpl<dim, T> {};

template<typename T>
class Vector<2, T> : public VectorImpl<2, T>
{
public:
   T x() const { ... }
};

3.

您不需要定义 VecType !在模板中,您可以只使用Vector。它将自动推断出引用具有正确参数的类。

最终编译结果:

#include <array>

template<int dim, typename T>
class VectorImpl
{
public:
    //typedef Vector<dim, T> VecType;

    VectorImpl() {  }
    VectorImpl(const VectorImpl& other) {  }
    VectorImpl& operator=(const VectorImpl& other) { return *this; }

    VectorImpl operator+(const VectorImpl& other) { return *this; }
    VectorImpl operator-(const VectorImpl& other) { return *this; }
    T operator*(const VectorImpl& other) { return 0; }

protected:
    std::array<T, dim> elements;
};

template <int dim, typename T = float>
class Vector : public VectorImpl<dim, T> {};

template<typename T>
class Vector<2, T> : public VectorImpl<2, T>
{
public:
    T x() const { return this->elements[0]; }
    T y() const { return this->elements[1]; }
};

template<typename T>
class Vector<3, T> : public VectorImpl<2, T>
{
public:
    T x() const { return this->elements[0]; }
    T y() const { return this->elements[1]; }
    T z() const { return this->elements[2]; }
};

int main()
{
    Vector<2> v;
    Vector<3> vv;
    v + v;
    vv.z();
}

1.

When partially specializing a template, only supply the template parameters that are actually a parameter. Since you've already fixed dim to be 2 or 3, there's no need to specify it again.

template<typename T>
class Vector<2, T>
{
   ....

2.

Specializing a class really means changing the whole declaration. Therefore, the members s of the generic Vector<dim, T> will not be available in the specialized Vector<2, T>. You could make the generic Vector<dim, T> as into an internal base class, and create a subclass just for specialization:

template<int dim, typename T>
class VectorImpl;

...

template<int dim, typename T = float>
class Vector : public VectorImpl<dim, T> {};

template<typename T>
class Vector<2, T> : public VectorImpl<2, T>
{
public:
   T x() const { ... }
};

3.

You don't need to define VecType! Inside a template, you could just use Vector. It will automatically be deduced to refer to the class with the right parameters.

The end result that compiles:

#include <array>

template<int dim, typename T>
class VectorImpl
{
public:
    //typedef Vector<dim, T> VecType;

    VectorImpl() {  }
    VectorImpl(const VectorImpl& other) {  }
    VectorImpl& operator=(const VectorImpl& other) { return *this; }

    VectorImpl operator+(const VectorImpl& other) { return *this; }
    VectorImpl operator-(const VectorImpl& other) { return *this; }
    T operator*(const VectorImpl& other) { return 0; }

protected:
    std::array<T, dim> elements;
};

template <int dim, typename T = float>
class Vector : public VectorImpl<dim, T> {};

template<typename T>
class Vector<2, T> : public VectorImpl<2, T>
{
public:
    T x() const { return this->elements[0]; }
    T y() const { return this->elements[1]; }
};

template<typename T>
class Vector<3, T> : public VectorImpl<2, T>
{
public:
    T x() const { return this->elements[0]; }
    T y() const { return this->elements[1]; }
    T z() const { return this->elements[2]; }
};

int main()
{
    Vector<2> v;
    Vector<3> vv;
    v + v;
    vv.z();
}
不必了 2024-12-30 06:31:46

部分专业化应该是这样的:

template <int Dim, typename T = float> class Vector; // primary

template <typename T> class Vector<2, T> { /* ... */ };
template <typename T> class Vector<3, T> { /* ... */ };

The partial specialization should be something like this:

template <int Dim, typename T = float> class Vector; // primary

template <typename T> class Vector<2, T> { /* ... */ };
template <typename T> class Vector<3, T> { /* ... */ };
倾城°AllureLove 2024-12-30 06:31:46

你可以这样做:

#include <array>
template<int dim, typename T = float>
class Vector
{
public:
    typedef Vector<dim, T> VecType;
    Vector() { /**/ }
    Vector(const VecType& other) { /**/ }
private:
    std::array<T, dim> elements;
};

template<typename T>
class Vector<2, T>
{
public:
    T x() const { return elements[0]; }
    T y() const { return elements[1]; }
private:
    std::array<T, 2> elements;
};

template<typename T>
class Vector<3, T>
{
public:
    T x() const { return elements[0]; }
    T y() const { return elements[1]; }
    T z() const { return elements[2]; }
private:
    std::array<T, 3> elements;
};

int main(int argc, char **argv)
{
    Vector<2> v2;
    v2.x();
    Vector<3> v3;
    v3.z();
    return 0;
}

这可以在 gcc 4.5.2 中编译(不要运行它......)。

但是,这样,您将无法在特化中使用主模板中定义的成员函数的任何成员变量。

You can do it like this:

#include <array>
template<int dim, typename T = float>
class Vector
{
public:
    typedef Vector<dim, T> VecType;
    Vector() { /**/ }
    Vector(const VecType& other) { /**/ }
private:
    std::array<T, dim> elements;
};

template<typename T>
class Vector<2, T>
{
public:
    T x() const { return elements[0]; }
    T y() const { return elements[1]; }
private:
    std::array<T, 2> elements;
};

template<typename T>
class Vector<3, T>
{
public:
    T x() const { return elements[0]; }
    T y() const { return elements[1]; }
    T z() const { return elements[2]; }
private:
    std::array<T, 3> elements;
};

int main(int argc, char **argv)
{
    Vector<2> v2;
    v2.x();
    Vector<3> v3;
    v3.z();
    return 0;
}

This can compile in gcc 4.5.2 (Don't run it ...).

However, in this way, you will not be able to use any of the member variable of member function define in your main template in the specialization.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文