在编译时设置Vector的值

时间:2017-11-09 00:21:30

标签: c++ templates compilation compile-time

我实施了自己的教育矢量课程。这是一个简化的片段:

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 个答案:

答案 0 :(得分:3)

您只需使用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...};
    }
};

Live Demo

如果提供了错误数量的元素,那么静态断言将在编译时提供一个很好的错误,说明到底出了什么问题。