Установить значения вектора во время компиляции
Я реализовал свой собственный векторный класс для образования. Вот упрощенный фрагмент:
template <size_t DIM>
class Vector
{
private:
float _data[DIM];
public:
void Set();
float Length() const;
float& operator[](size_t index);
}
Я реализовал Length()
и operator[]
методы, мой вопрос сейчас заключается в том, как реализовать Set()
метод, который нужно принять DIM
аргументов не больше и не меньше и предполагается заполнить вектор.
Я решил эту проблему с помощью следующих настроек:
void Set(const std::array<float, DIM>& input)
{
std::copy(input.begin(), input.end(), _data);
}
Проблема с этим подходом заключается в том, что я должен использовать Set()
метод следующим образом:object.Set({1,2,3})
а не так object.Set(1,2,3)
и кроме того, компилятор только жалуется, если количество аргументов внутри {}
больше чем DIM
и не меньше.
Я также использовал второй хак, который решает эту проблему, но создает другой:
size_t index = 0;
template <typename FIRST>
void Set(FIRST first)
{
_data[index] = first;
index = 0;
}
template <typename FIRST, typename ... SECOND>
void Set(FIRST first, SECOND... second)
{
_data[index] = first;
++index;
Set2(second...);
}
Теперь я могу использовать object.Set(1,2,3)
Однако это может занять меньше или больше, чем DIM
аргументы и, следовательно, не очень хороший вариант. Я знаю, что могу это исправить, проверяя во время выполнения, но я хочу, чтобы компилятор жаловался, когда во время компиляции нет точно DIM-аргументов. Несколько советов о том, как улучшить мои решения, были бы мне приятны:)
1 ответ
Вы можете просто использовать static_assert
:
template <size_t DIM>
class Vector
{
private:
std::array<float, DIM> data_;
public:
// Other stuff
template <typename... Args>
void Set(Args... args)
{
static_assert(sizeof...(args) == DIM,
"Wrong number of args");
data_ = {args...};
}
};
Если указано неверное количество элементов, то статическое утверждение во время компиляции выдаст приятную ошибку, сообщив, что именно пошло не так.