user7769147
user7769147

Reputation: 1659

Pass explict empty arguments pack

I'm trying to overload constructors as follows

struct foo
{
    foo(int, int);

    template<typename... Args>
    foo(int, int, Args... args);
}

foo(int, int) behaves differently from foo(int, int, empty_arguments_pack). I want foo(1, 2) to call foo(int, int) and something like foo(1, 2, ) to call foo(int, int, Args...). How can i do that?

Upvotes: 1

Views: 81

Answers (2)

Jarod42
Jarod42

Reputation: 217398

You cannot call explicitly template constructor as foo<>(1, 2) /*Illegal*/

You might create other tagged overloads foo(special_tag, int, int/*, Args...*/) to solve your issue

struct special_tag{};

class foo
{
public:
    template<typename... Args>
    foo(special_tag, int i1, int i2, Args... args) { /**/}

    foo(int, int) { /*...*/}

    // And possibly
    template<typename... Args>
    foo(int i1, int i2, Args... args) : foo(special_tag{}, i1, i2, args...) { /*...*/}
};

Now, you can use:

foo(1, 2); // foo(int, int)
foo(special_tag{}, 1, 2); // foo(special_tag, int, int, Args...)
foo(special_tag{}, 1, 2, 3); // foo(special_tag, int, int, Args...)
// And possibly:
foo(1, 2, 3); // foo(int, int, Args...) so foo(special_tag, int, int, Args...)

Upvotes: 2

jerry_fuyi
jerry_fuyi

Reputation: 503

If you would like foo(1, 2) to call the variadic template constructor, what will you write when you want to call foo(int, int)?

My suggestion is:

  1. Declare a nested class;

  2. Specify the template constructor;

  3. Append an object of the nested class after two ints if you want to call the variadic template constructor.

Your code should look like:

class Foo
{
public:
    class Special {};

    Foo(int, int) { /* ... */ }

    template <typename... Args>
    Foo(int, int, Args&&...) { /* ... */ }

    template <typename... Args>
    Foo(int, int, Special, Args&&...) { /* ... */ }
};

Upvotes: 0

Related Questions