Как перебрать 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 с using директива для того, чтобы передать эти значения в конструктор вспомогательной структуры, которая отображается в цикле for в классе DimensionPack?

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 каждый элемент. Вы можете напрямую инициализировать вектор со всеми элементами.

2

Другие решения

Зачем ты это делаешь?

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 возвращает constexpr массив bools, размеры которых нечетны. Это легче перебрать, чем целочисленная последовательность.

odd_dims Тип не будет компилироваться, если таковые имеются Dims являются 0, Нет необходимости проверок во время выполнения.

Динамическое распределение здесь для каждого DimensionPack кажется очень странным способом решения этой проблемы.

0

По вопросам рекламы [email protected]