简体   繁体   English

C ++模板专门化声明

[英]c++ template specialization-specific declaration

Basically, what i'm trying to do is build a Vector template, with two arguments: dimensions, and variable type. 基本上,我想做的是构建一个Vector模板,其中包含两个参数:维度和变量类型。

template <typename Type, unsigned ElementCount>
class TVector
    {
    private:
    public:
        union
            {
            struct
                {
                Type X, Y, Z, W;
                };
            struct
                {
                Type Red, Green, Blue, Alpha;
                };
            Type Values[ElementCount];
            };
    }

It all works ok, but as you may have noticed, this is only for 4-element vectors, since only the Values variable is dependent on ElementCount. 一切正常,但您可能已经注意到,这仅适用于4元素向量,因为只有Values变量依赖于ElementCount。 ElementCount=1 declares only X and Red, 2 declares Y and Green, and so on... So, what i wanted was to have the other variables being declared also depending on the ElementCount value. ElementCount = 1仅声明X和Red,2声明Y和Green,依此类推...因此,我想要的是根据ElementCount值声明其他变量。

Is it at all possible? 有可能吗? I don't think so, but wanted to make sure, anyway. 我不这么认为,但无论如何都想确保。

I was thinking of declaring that whole union separately and passing it along as a template parameter, but that's ugly as hell.... 我当时正在考虑分别声明整个联合,并将其作为模板参数传递,但这很丑陋。

EDIT: Dammit. 编辑:该死。 Now i remembered something... What about the constructor-by-value? 现在我想起了什么...按值构造函数呢?

The argument count is dependent of the template parameter ElementCount... How to do this? 参数计数取决于模板参数ElementCount ...如何执行此操作?

You could do it with partial specialization. 您可以通过部分专业化来实现。 Something like 就像是

template<typename T, unsigned N>
struct S
{
    union
    {
        struct
        {
            T X, Y, Z, W;
        };

        struct
        {
            T Red, Green, Blue, Alpha;
        };

        T Values[N];
    };
};

template<typename T>
struct S<T, 1>
{
    union
    {
        struct
        {
            T X;
        };

        struct
        {
            T Red;
        };

        T Values[1];
    };
};

int main()
{
    using S1 = S<char, 1>;
    using S5 = S<char, 5>;

    std::cout << "sizeof(S1) = " << sizeof(S1) << '\n';
    std::cout << "sizeof(S5) = " << sizeof(S5) << '\n';
}

It should print 它应该打印

sizeof(S1) = 1
sizeof(S5) = 5

Also, doing eg 另外,例如

S1 s1;
s1.Y = 0;

should give you an error that the structure have no member Y . 应该给您一个错误,该结构没有成员Y

Yes it's a lot more to write (or copy-paste) but it should solve your problem. 是的,编写(或复制粘贴)内容要多得多,但它可以解决您的问题。

You don't need to pass in the whole union -- just the struct and the type of the fields. 您不需要传递整个联合-只需传递结构和字段的类型即可。 I've also added a syntactic sugar in operator-> so you don't have to reference the .Names part if you don't wish. 我还在operator->中添加了语法糖,因此,如果您不想的话,不必引用.Names部分。

#include <iostream>

struct PointStruct {
    int X;
    int Y;
    int Z;
};

struct ColorStruct {
    int Red;
    int Green;
    int Blue;
    int Alpha;
};


template <typename Type, typename Struct>
class TVector
{
public:
    const static int LEN = sizeof(Struct) / sizeof(Type);
    union
        {
            Struct Names;
            Type Values[LEN];
        };
    Struct* operator->() { return &Names; }
    const Struct* operator->() const { return &Names; }
};

int main(int argc, const char** argv) {
    TVector < int, PointStruct > points;
    points.Names.X = 55;
    points.Names.Y = -67;
    points.Names.Z = 42;
    for (int x = 0; x < points.LEN; ++x) {
        std::cout << "points[" << x << "]: " << points.Values[x] << std::endl;
    }
    points.Values[1] = 135;
    std::cout << "points->Y: " << points->Y << std::endl;
    TVector < int, ColorStruct > colors;
    colors.Names.Red = 1;
    colors.Names.Green = 2;
    colors.Names.Blue = 3;
    colors.Names.Alpha = 4;
    for (int x = 0; x < colors.LEN; ++x) {
        std::cout << "colors[" << x << "]: " << colors.Values[x] << std::endl;
    }
}

With g++ 4.3 I get 使用g ++ 4.3我得到

points[0]: 55
points[1]: -67
points[2]: 42
points->Y: 135
colors[0]: 1
colors[1]: 2
colors[2]: 3
colors[3]: 4

I would avoid specialization at this level, rather do it inside the union itself: 我会避免在此级别进行专业化,而应在工会内部进行:

template <typename T> struct X   { T x; };
template <typename T> struct XY  { T x, y; };
...

template <typename T, int Count>
struct CountToXYZWType {};
template <typename T> struct CountToXYZWType<T,1> { typedef X<T>  type; };
template <typename T> struct CountToXYZWType<T,2> { typedef XY<T> type; };
...

template <typename T, int Count>
struct TVector {
   union {
      typename CountToXYZWType<Count>::type;
      // similarly CountToColorType<Count> ...
      T values[Count];
   }
...

}; };

Ok, first of all, a big thank you for everyone, for all the ideas. 好的,首先,非常感谢大家以及所有的想法。 I finally managed to do what i wanted, using a mix of all you suggested. 最终,我综合使用了您提出的所有建议来完成自己想做的事情。

second, let me explain, then. 其次,让我解释一下。 I wanted to rewrite my math library. 我想重写我的数学库。 I basically had a class for 2d, 3d and 4d vectors each. 我基本上有一个分别用于2d,3d和4d向量的类。 It was stupid, since most of the code is the same, so i decided to try to refactor using templates. 这很愚蠢,因为大多数代码都是相同的,所以我决定尝试使用模板进行重构。

I also had a small class named RGB and another called RGBA for obvious reasons :). 由于明显的原因,我也有一个名为RGB的小类,另一个名为RGBA的小类:)。

And as such, i embarked on this adventure with templates ( i'm not a big fan, but mainly because i can't understand them. they're certainly very useful ). 因此,我开始了使用模板的冒险活动(我不是一个忠实的粉丝,但主要是因为我听不懂它们。它们肯定非常有用)。

So, after several failed tries, I changed approach. 因此,在几次尝试失败之后,我改变了方法。 The final result is a mix of all the above and the kitchen sync. 最终结果是以上所有内容和厨房同步处理的混合。 A small taste, including member functions ( i had some trouble with those ), the union with the named member variables is available here: http://goo.gl/4Zlt20 包括成员函数在内的一些小问题(我对那些函数有些麻烦),可以在此处找到带有命名成员变量的联合: http : //goo.gl/4Zlt20

Now, for one final question, if i may... 现在,对于最后一个问题,我是否可以...

It all works the way i want it, but for some reason, i can't get rid of that "this->" on the inline functions. 一切都按我想要的方式工作,但是由于某种原因,我无法消除内联函数上的“ this->”。 Can anyone explain why? 谁能解释为什么?

Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM