2017-02-03 21 views
2

有这样的代码在我的源:我如何循环的std :: 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文件到本头文件编译,但是当我去编译另一个cpp文件,如包含它的main;它无法编译。

这是我得到的当前错误信息:

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<...>的指令中指定为Dimensions的各个元素,以便将这些值传递给DimensionPack类中的for循环中所见的帮助程序结构的构造函数?

+0

'index_sequence'适用于有数字且想要序列的情况。你已经有了一个序列,所以就使用它。 – Caleth

+0

@Caleth别人曾经提出过另一个相关问题的'index_sequence',这个问题源于这个问题。但是,下面的答案适用于我。感谢您的信息! –

回答

2

有没有需要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每个元素。您可以直接使用所有元素初始化矢量。

+0

谢谢!这非常简单。我只是没有考虑用可变参数初始化矢量。现在我实际上可以开始在我班的实施中工作并完成一些工作! –

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尺寸为奇数的bools数组。这比遍历序列更容易迭代。

如果有任何Dims0,则odd_dims类型将无法编译。不需要运行时检查。

在每个DimensionPack的基础上的动态分配似乎是一个很奇怪的方法来解决这个问题。