可变参数模板参数包,仅接受无符号整数或size_t作为其类型 [英] Variadic template parameter pack to accept only unsigned ints or size_t as its type

查看:85
本文介绍了可变参数模板参数包,仅接受无符号整数或size_t作为其类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用带有可变参数的一组模板类.我前面有几种选择可以选择.在声明或定义任何模板之前,我目前具有以下原型:我对模板很熟悉,但是在使用模板时我对可变参数类型没有太多的经验,因此语法有时会让我有些困惑.由于它们都是空壳,因此它们当前正在编译.

I'm trying to use a set of template classes with a variadic parameter. I have several options ahead of me that I could choose from. Before any of my templates are declared or defined I currently have these prototypes: I'm familiar with templates but I haven't had much experience with variadic types when working with templates so the syntax does get a little confusing to me at times. Being that they are all empty shells they do currently compile.

template<typename ClassType, typename... Args>  class MatrixReference;
template<typename ClassType, typename... Args>  class MatrixStorage;
template<typename ClassType, typename... Args>  class MatrixAllocation;

我有一个User End Class,将根据使用意图使用这些类;目前,它是一个空壳,直到我以适当的行为正确定义了其他类:

I have a User End Class that will use these classes depending on the intentions of use; it is currently an empty shell for now until I get the other classes defined correctly with the appropriate behavior:

template<typename ClassType, typename... Args>
class Matrix {      
};

上面显示的原型中的其余类将从基类继承,以便上述用户类将具有一个容器,以便该容器将是:std::vector<std::unique_ptr<MatrixBase>>std::vector<shared_ptr<MatrixBase>>,并且矢量将仅包含列出的原型中的每种类型的1种.例如,vector [0]将包含MatrixStorage,vector [1]将包含MatrixReference,而vector [2]将包含MatrixAllocation.顾名思义,这些类别中的每一个都有不同的职责.存储类将包含元素的原始堆栈副本.引用类将用于引用这些副本.在堆上声明元素时将使用分配类.基类如下:

The rest of the class from the prototypes shown above will inherit from a base class so that the above user class will have a container of them such that the container would be: std::vector<std::unique_ptr<MatrixBase>> or std::vector<shared_ptr<MatrixBase>> and the vector will only ever contain 1 of each type from the listed prototypes. For instance vector[0] would contain a MatrixStorage, vector[1] would container a MatrixReference and vector[2] would contain a MatrixAllocation. Each of these classes have different responsibilities as their names suggest. The storage class will contain a raw stack copy of the elements. The reference class will be use to reference those copies. The allocation class will be used when the elements are declared on the heap. The base class looks like this:

template <typename ClassType = void>
class MatrixBase {
protected:
    MatrixBase(){}
    virtual ~MatrixBase(){}
}; // Matrix

我还考虑过要从非模板基继承它们,因为此类不做任何事情,但其目的是能够将不同的类类型存储到单个容器中.我可能会继续将其更改为非模板类​​型,但现在我将按照原样使用它,以遵循其派生类型的约定.

I have also thought about inheriting them from a non template base as this class does nothing but serve the purpose of being able to store different class types into a single container. I may go ahead and change this to a non template type but for now I'm using it as is to stay with the conventions of its derived types.

现在要声明我的类模板:我真的只需要在其中使用其中一个模板,因为它们都遵循相同的模式,但是无论如何我都将显示这三个模板,因为它们当前是空壳.

Now onto the declaration of my class templates: I really only need to use one of them here since all follow the same pattern, but I'll show all 3 anyway since they are currently empty shells.

// Stores All Of The Contents Of The Matrix
template<typename ClassType, typename... Args>
class MatrixStorage : public MatrixBase<ClassType> {
}; // MatrixStorage    

// Used To Reference The Storage Class Of The Matrix
template<typename ClassType, typename... Args>
class MatrixReference : public MatrixBase<ClassType> {
}; // MatrixReference

// Used Only When User Wants To Create A Matrix On The Heap
template<typename ClassType, typename... Args>
class MatrixAllocation : public MatrixBase<ClassType> {
}; // MatrixAllocation

我正在寻找的设计方法是,当使用此类时,它遵循以下模式:第一种类型始终是矩阵将存储为int,float或其他用户定义的数据类型类型;下一个参数是使用可变参数的地方,因此,如果这样实例化模板:

The design approach that I'm looking for is that when this class is used it follows the pattern where the first type is always the type of data the matrix will store either it be an int, float, or some other user defined type; the next parameter is where the use of a variadic parameter comes in so that if one instantiates a template as such:

Matrix<float,2,2> mat2x2; // Default constructor making it empty

这将生成一个2x2大小的浮点矩阵

This will generate a 2x2 sized Matrix of floats

Matrix<int,3,3,3> mat3x3x3; 

这将生成一个3x3x3的整数体积矩阵

This would generate a 3x3x3 volumetric matrix of ints

因此可变参数模板部分将始终为+整数,最小要求为Matrix<type, 1>,在某种意义上,这将是标量或单个元素矩阵或1x1矩阵.

So the variadic template part will always be + integers and the minimal requirement would be Matrix<type, 1> where this would be in a sense a scalar or a single element matrix or a 1x1 matrix.

这是向我介绍一些选项的地方.我可以使用以下

This is where I'm presented with a few options. I could use the following

  • size_t ... N
  • 未签名... D
  • typename ... Args

当前您可以看到,它是使用最后一个选项声明的.现在是主要问题:

Currently at the moment as you can see it is declared with the last of the choices. So now comes the main question:

如果我决定在有帮助类的地方使用Parameter Pack:

If I decided to use the Parameter Pack where I have a helper class as such:

template <typename ClassType,typename... Dimensions>
class DimensionPack {
public: 
    typename std::tuple<ClassType, std::tuple<Dimensions...> >::type Dim;
    const unsigned int numarguments = sizeof...(Dimensions);
};

问题变成了;是否有一种已知的方法可以使可变参数的类型相同,即size_tunsigned int?如果是这样,将不胜枚举示例,或者参考链接也将有所帮助;我已经搜索过,但是没有找到任何有用的东西,足以帮助我解决这个问题.

The question becomes; is there a known way to make the Variadic Parameter of the same type namely either size_t or unsigned int? If so an example would be appreciated or a reference link would help as well; I've searched and haven't found anything helpful that is similar enough to help me through this.

如果没有,我不介意使用size_tunsigned int,但是我更喜欢能够使用助手模板以这种方式为我打包和解压缩可变参数必须在每个类中都实现这一点.

If there isn't I don't mind having to use size_t or unsigned int but I was preferring to be able to use the helper template to pack and unpack the variadic parameters for me this way I don't have to implement that in each and every class.

我还有另外2个派生类(此处未显示),但其中一个将用于将它们记录到屏幕上,而另一个将用于从文件读取和解析以及写出到文件中.

I also have a 2 other derived classes not shown here but one would be used with logging them to the screen, where the other would be used with reading and parsing from a file and writing out to a file.

也要注意:对于超大型数据集或超大型矩阵:我也可以使用此帮助器类:

Also as a side note: For extremely large data sets or extremely large sized Matrices: I also have this helper class to use for them:

template<typename ClassType, std::size_t bufferSize>
class MatrixBuffer {
    static std::vector<ClassType> matrixBuffer = std::vector<ClassType>().reserve( bufferSize );
};

修改

我忘记将其添加到原始问题中,但是为了更加清晰起见,现在添加它.我确实需要测试每个可变参数的值,看它是否为奇数或偶数,并将它们的结果存储到一个向量中,该向量的大小与偶数为0或奇数为1的参数的大小相同.这就是我之所以倾向于使用参数包的原因之一,因为我可以将其传递给一个辅助函数,该函数将返回所需的向量.

I forgot to add this to the original question but I'm adding it now for a little more clarity. I do have a need to test each variadic parameter's value to see if it is odd or even and the results of them will be stored into a vector with a size of the amount of parameters storing a 0 for even or a 1 for odd. This is one of the reasons why I was leaning towards the use of a parameter pack because I could just pass it to a helper function that would return back the vector that is needed.

推荐答案

std::size_t... Argstypename... Args不同.第一个会期望像这样的 integers

std::size_t... Args and typename... Args are not the same. The first would expect integers like

Matrix<float,2,2> mat2x2;

而第二个会期望使用类型.
当然,您可以使用 std :: integral_constant ,但是更详细:

while the second would expect types instead.
Of course, you could use std::integral_constant, but that'd be more verbose:

template <std::size_t N>
using size = std::integral_constant<std::size_t, N>;

Matrix<float,size<2>,size<2>> mat2x2;

另一方面,您可以使用 std :: index_sequence :

On the other hand you could use std::index_sequence:

template<typename ClassType, std::size_t... Dims>
class Matrix {
    using Dimensions = std::index_sequence<Dims...>;
};

这篇关于可变参数模板参数包,仅接受无符号整数或size_t作为其类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆