Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ variadic template - limit number of args

I have a variadic template class with set function, that fills interal array:

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];
};

Problem is, that I can call this

Vector<3> v;
v.SetValue(0, 1, 2, 4, 5);

and it compiles correctly. Can I limit this to not compile? I can use static_assert, but is it possible without it?

like image 813
Martin Perry Avatar asked Oct 31 '25 20:10

Martin Perry


1 Answers

Yes, this is possible, without static_assert. For example, let's assume we want our vector class to only be assignable with the name number of arguments as the dimension of the vector, you can use:

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) {}
};

This just uses std::enable_if in combination with sizeof... to enable or disable the specific assign function.

So the following will compile:

vector<3> x;
x.assign(1, 2, 3);

Live demo

but this won't:

vector<3> x;
x.assign(1, 2, 3, 4);

Live demo

with (for Clang):

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

and neither will this:

vector<3> x;
x.assign(1, 2);

Live demo

with a similar error message.

like image 162
Shoe Avatar answered Nov 03 '25 12:11

Shoe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!