如何迭代std :: index_sequence

时间:2017-02-03 08:10:10

标签: c++ c++11 c++14 variadic-functions index-sequence

我在源代码中有这段代码:

template <std::size_t... Dims>
class DimensionPack {
public: 
    using Dimensions = std::index_sequence<Dims...>;
    static const std::size_t total_dimensions = sizeof...(Dims);
    std::vector<unsigned int> even_or_odd;

public:
    DimensionPack() {
        unsigned idx = 0;
        for ( ; idx < total_dimensions; idx++ ) {
            //MatrixDimensionOddOrEven mdoe( Dimensions[idx] );
            //unsigned int val = mdoe.even_or_odd;
            //even_or_odd.push_back( val );
        }
    }
};

注释的代码行是有问题的代码。我不熟悉使用std::indx_sequence<>并且我已经阅读了MSD上的文档,但仍然不确定它,特别是当它与using指令一起使用时。

此模板类将用作其他可变参数模板类的参数包,用于存储和提取可变参数列表中的数据。在这个类的构造函数中,我使用这个结构的构造函数和私有方法来检查值并返回其偶数或奇数的状态并从其公共常量成员获取值:

struct MatrixDimensionOddOrEven {
    const unsigned int even_or_odd; 
    explicit MatrixDimensionOddOrEven( unsigned int odd_or_even ) : even_or_odd( test( odd_or_even ) ) {}

private:
    const unsigned int test( unsigned int value ) const {
        if ( value == 0 ) {
            std::ostringstream strStream;
            strStream << __FUNCTION__ << "invalid number: " << value << " must be >= 1.";
            Logger::log( strStream, Logger::TYPE_ERROR );
            throw ExceptionHandler( strStream );
        }
        return ( ((value % 2) == 0) ? ODD : EVEN );
    }
};

这个头文件的cpp文件编译,但是当我去编译包含它的main之类的另一个cpp文件时;它无法编译。

这是我收到的当前错误消息:

1>------ Build started: Project: FileTester, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\users\skilz80\documents\visual studio 2015\projects\filetester\filetester\matrix.h(44): error C2540: non-constant expression as array bound
1>  c:\users\skilz80\documents\visual studio 2015\projects\filetester\filetester\matrix.h(41): note: while compiling class template member function 'DimensionPack<2,3,4>::DimensionPack(void)'
1>  c:\users\skilz80\documents\visual studio 2015\projects\filetester\filetester\main.cpp(336): note: see reference to function template instantiation 'DimensionPack<2,3,4>::DimensionPack(void)' being compiled
1>  c:\users\skilz80\documents\visual studio 2015\projects\filetester\filetester\matrix.h(60): note: see reference to class template instantiation 'DimensionPack<2,3,4>' being compiled
1>  c:\users\skilz80\documents\visual studio 2015\projects\filetester\filetester\main.cpp(155): note: see reference to class template instantiation 'Matrix<float,2,3,4>' being compiled
1>c:\users\skilz80\documents\visual studio 2015\projects\filetester\filetester\matrix.h(45): error C2228: left of '.even_or_odd' must have class/struct/union
1>c:\users\skilz80\documents\visual studio 2015\projects\filetester\filetester\matrix.h(45): error C2789: 'val': an object of const-qualified type must be initialized
1>  c:\users\skilz80\documents\visual studio 2015\projects\filetester\filetester\matrix.h(45): note: see declaration of 'val'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

编译错误并没有给我带来麻烦;在使用可变参数模板和参数包时,它更多地是关于这种语法。那么我如何正确编写语法以获取std::index_sequence<...>的{​​{1}}的各个元素,并将Dimensions指令分配给using,以便将这些值传递给辅助结构的构造函数在DimensionPack类的for循环中看到了什么?

2 个答案:

答案 0 :(得分:3)

不需要index_sequence。这样做:

template <std::size_t... Dims>
class DimensionPack {
public:
    std::vector<unsigned int> even_or_odd;

public:
    DimensionPack()
        : even_or_odd{MatrixDimensionOddOrEven{Dims}.even_or_odd...}
    {
    }
};

作为奖励,它的美妙之处在于你不需要push_back每个元素。您可以使用所有元素直接初始化矢量。

答案 1 :(得分:0)

你为什么要这样做?

template <std::size_t... Dims>
class DimensionPack {
public:
   using odd_dims = std::integer_sequence<bool,
     std::enable_if_t<Dims!=0, bool>(Dims%2)...
   >;
   constexpr static std::array<bool, sizeof...(Dims)> get_odd_dims() {
     return {{ (bool)(Dims%2)... }};
   }
};

现在odd_dimsinteger_sequence,其维度是偶数和奇数。

get_odd_dims返回constexpr个bool数组,其维度为奇数。这比整数序列更容易迭代。

如果odd_dimsDims 0import numpy as np temp=np.array([p[m]*A[m] for m in range(M)]) B=sum(temp); 类型将无法编译。无需运行时检查。

此处基于per-DimensionPack的动态分配似乎是解决此问题的一种非常奇怪的方法。