如何遍历 std::index_sequence
How to iterate over 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
指令一起使用时。
此模板 class 将用作其他可变参数模板 class 的参数包,用于从可变参数列表中存储和提取数据。在这个 class 的构造函数中,我使用这个结构的构造函数和私有方法来检查值并 return 它的状态是偶数还是奇数,并从它的 public 常量中获取值成员:
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 ==========
给我带来麻烦的不是编译器错误,而是编译器错误。在可变参数模板和参数包的使用中,更多关于这种语法对我来说有点新。那么我该如何正确编写语法来获取使用 using
指令分配给 Dimensions
的 std::index_sequence<...>
的各个元素,以便将这些值传递给辅助结构的构造函数在 DimensionPack class?
的 for 循环中可以看到
不需要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
每个元素。您可以直接用所有元素初始化向量。
你为什么要这样做?
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_dims
是一个 integer_sequence
维度是偶数和奇数。
get_odd_dims
returns 一个 constexpr
维度为奇数的布尔数组。这比整数序列更容易迭代。
如果 Dims
是 0
,odd_dims
类型将无法编译。无需运行时检查。
此处基于per-DimensionPack的动态分配似乎是一种非常奇怪的解决方法。
我的源代码中有这段代码:
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
指令一起使用时。
此模板 class 将用作其他可变参数模板 class 的参数包,用于从可变参数列表中存储和提取数据。在这个 class 的构造函数中,我使用这个结构的构造函数和私有方法来检查值并 return 它的状态是偶数还是奇数,并从它的 public 常量中获取值成员:
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 ==========
给我带来麻烦的不是编译器错误,而是编译器错误。在可变参数模板和参数包的使用中,更多关于这种语法对我来说有点新。那么我该如何正确编写语法来获取使用 using
指令分配给 Dimensions
的 std::index_sequence<...>
的各个元素,以便将这些值传递给辅助结构的构造函数在 DimensionPack class?
不需要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
每个元素。您可以直接用所有元素初始化向量。
你为什么要这样做?
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_dims
是一个 integer_sequence
维度是偶数和奇数。
get_odd_dims
returns 一个 constexpr
维度为奇数的布尔数组。这比整数序列更容易迭代。
如果 Dims
是 0
,odd_dims
类型将无法编译。无需运行时检查。
此处基于per-DimensionPack的动态分配似乎是一种非常奇怪的解决方法。