C++ 可变参数模板 - 限制参数数量

Mar*_*rry 4 c++ templates variadic-templates c++11

我有一个带有 set 函数的可变参数模板类,它填充内部数组:

template <size_t Dim>
class Vector
{
public:

    void SetValueTemplate(size_t index)
    {
        return;
    }

    template <typename X0, typename ...Xn>
    void SetValueTemplate(size_t index, X0 x0, Xn... xn)
    {
        val[index] = x0;
        SetCenterValueTemplate(index + 1, xn...);
    }

    template <typename ...X0>
    void SetValue(X0... t0)
    {
        SetValueTemplate(0, t0...);
    }

private:
    double val[Dim];
};
Run Code Online (Sandbox Code Playgroud)

问题是,我可以称之为

Vector<3> v;
v.SetValue(0, 1, 2, 4, 5);
Run Code Online (Sandbox Code Playgroud)

并且它编译正确。我可以限制它不编译吗?我可以使用static_assert,但是没有它也可以吗?

Sho*_*hoe 5

是的,这是可能的,无需static_assert. 例如,假设我们希望我们的vector类只能使用参数的名称数量作为向量的维度进行分配,您可以使用:

template<std::size_t Dim>
struct vector {
    template <typename X0, typename ...Xn>
    typename std::enable_if<sizeof...(Xn) + 1 == Dim, void>::type
    assign(X0 x0, Xn... xn) {}
};
Run Code Online (Sandbox Code Playgroud)

这只是std::enable_if与 结合使用sizeof...来启用或禁用特定的分配功能。

因此,以下内容将编译:

vector<3> x;
x.assign(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)

Live demo

但这不会:

vector<3> x;
x.assign(1, 2, 3, 4);
Run Code Online (Sandbox Code Playgroud)

Live demo

与(对于 Clang):

main.cpp:14:7: error: no matching member function for call to 'assign'
    x.assign(1, 2, 3, 4);
    ~~^~~~~~
Run Code Online (Sandbox Code Playgroud)

这也不会:

vector<3> x;
x.assign(1, 2);
Run Code Online (Sandbox Code Playgroud)

Live demo

有类似的错误消息。

  • 它之所以有效,是因为 [sizeof...](http://en.cppreference.com/w/cpp/language/sizeof...) 返回参数包中的元素数量。 (2认同)