当前位置: 首页 > 知识库问答 >
问题:

可变模板参数包仅接受无符号整数或大小\u t作为其类型

汪博艺
2023-03-14

我试图使用一组带有可变参数的模板类。我面前有几个选择,我可以选择。在声明或定义任何模板之前,我目前拥有这些原型:我熟悉模板,但在使用模板时没有太多可变类型的经验,因此语法有时会让我感到有点困惑。因为它们都是空的shell,所以它们当前正在编译。

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

我有一个用户终端类,它将根据使用意图使用这些类;在我使用适当的行为正确定义其他类之前,它目前是一个空壳:

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

上面显示的原型类的其余部分将从基类继承,这样上面的用户类将拥有它们的容器,容器将是:std::vector

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

我还考虑过从非模板库继承它们,因为这个类除了能够将不同的类类型存储到单个容器中之外什么都不做。我可能会继续将其更改为非模板类型,但现在我使用它来保持其派生类型的约定。

现在来看看我的类模板的声明:我真的只需要在这里使用其中一个,因为所有模板都遵循相同的模式,但是我还是会显示所有3个模板,因为它们目前都是空shell。

// 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或其他用户定义的类型;下一个参数是可变参数的使用,因此,如果将模板实例化为:

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

这将生成2x2大小的浮动矩阵

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

这将生成3×3×3的整数体积矩阵

所以可变模板部分总是整数,最小要求是矩阵

在这里,我有几个选择。我可以用下面的

  • 大小\u t。。。N

目前,正如您所看到的,它是用最后一个选项声明的。现在主要的问题来了:

如果我决定使用参数包,其中我有一个助手类:

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

问题变成了;是否有一种已知的方法来生成相同类型的可变参数,即size\u t无符号int?如果是这样的话,请举个例子或参考链接也会有帮助;我已经搜索过了,但没有找到任何类似的东西来帮助我度过难关。

如果没有,我不介意必须使用size\tunsigned int,但我更愿意使用帮助器模板为我打包和解包可变参数,这样我就不必在每个类中都实现。

我也有2个其他派生类没有显示在这里,但一个将用于将它们记录到屏幕上,另一个将用于读取和解析文件并写入文件。

顺便说一下:对于非常大的数据集或非常大的矩阵:我也有这个助手类可以用于它们:

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

编辑

我忘了在原来的问题上加上这个,但为了更清楚一点,我现在加上它。我确实需要测试每个可变参数的值,看看它是奇数还是偶数,它们的结果将被存储到一个向量中,向量的大小等于存储0表示偶数或1表示奇数的参数量。这就是我倾向于使用参数包的原因之一,因为我可以将它传递给一个助手函数,该函数将返回所需的向量。


共有2个答案

孙项禹
2023-03-14

使用静态断言可以在编译时检查:

template <typename ClassType,typename... Dimensions>
class DimensionPack {
        public:
            DimensionPack(const Dimensions&... args){
                checkType<Dimensions...>(args...);
            }
            ~DimensionPack(){}
        private:
            template<typename T> void checkType(const T& t) {
                static_assert(std::integral_constant<bool, std::is_same<T, size_t>::value>(), "T is not of type size_t");
            }
            template<typename T, typename... V> void checkType(const T& t, const V&... v) {
                static_assert(std::integral_constant<bool, std::is_same<T, size_t>::value>(), "T is not of type size_t");
                checkType<V...>(v...);
            }
    };
鲜于意
2023-03-14

std::size\t。。。Args类型名。。。参数不相同。第一个会期望像这样的整数

Matrix<float,2,2> mat2x2;

而第二个则期望类型
当然,您可以使用std::integral_常量,但这会更加详细:

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

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

另一方面,您可以使用std::index_序列:

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

 类似资料:
  • 我对编程和C++相当陌生。我有一个函数,我想接受以模板化值作为参数的函数指针。我的意思是... 我有这个功能: 我试过的: 结果: .h:165:22:注意:已忽略候选模板:无法将“function ,allocator >&)”与“void(*)(bool,std::vectorstd::vectorstd::allocatorstd::tuple &)”void postgrescaller:

  • 我试图理解下面代码中的编译器错误。我有一个variadic模板函数,它接受具有指定类型的lambda,试图调用该函数会导致模板由于不匹配而不被视为有效的候选模板。 如果我将声明更改为不变: 然后它为上面的玩具示例工作,但对于真正的问题,我需要任意的论点。我是不是缺少了什么,或者还有什么方法可以做到这一点? 编辑:这被错误地标记为重复,我相信--受骗者没有回答我所问的问题。这个问题特别与这里的var

  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

  • 我有一个 类型,其中包含初始状态、当前状态和闭包列表,其中包含从初始状态计算当前状态所需的每个更改。这些使用 方法应用,该方法采用盒装闭包,使用它来修改当前状态,并将其添加到列表中。因为我希望这些是确定性的可重用的,所以它们是,而不是或。 我目前将闭包作为 而不是< code>dyn Trait,方法是否有可能接受任意的未装箱闭包。在这种情况下,我们的方法可以对闭包本身进行装箱,因此调用站点将变成

  • 我有以下代码: 这段代码会导致编译错误。使用< code>g -std=c 1z编译时,错误显示如下: 使用< code>clang -std=c 1z时,错误为: 我在MSYS2 MinGW-w64环境中运行这些。我的GCC版本是GCC 7.1.0,我的Clang版本是4.0.0;我在GCC和Clang中使用的标准库是与我的GCC编译器捆绑在一起的libstdc。 在我看来,对函数templat

  • 请考虑以下定义和演绎指南: 如果我尝试使用显式模板参数实例化 ,代码将正确编译: 如果我试图通过演绎指南实例化< code>foo... > G7产生编译器错误: clang 5 爆炸: wandbox上的实例 虽然clang肯定被窃听了(报告为问题#32673),但g拒绝我的代码是正确的吗?我的代码格式错误吗?