4

I got a example to illustrate my question:

#include <utility>

class Foo {
 public:
  Foo(int i) {}
};

template<typename T, typename ...Args>
class Bar {
 public:
  T t;
  Bar(Args &&... args) : t(std::forward<Args>(args)...) {}
};

and if I want to instantiate this template:

Bar<Foo> foo(1);

the compiler throw an error:

no matching function for call to ‘Bar<Foo>::Bar(int)’

So I have to write to this:

Bar<Foo, int> foo(1);

This is annoying, especially if I got some classes which have a long list of parameters.

So is there any way I can get rid of explicitly showing the types in the parameter packs

1 Answers1

6

If you want to constructor to forward, make that a template

template<typename T>
class Bar {
 public:
  T t;
  template<typename ...Args>
  Bar(Args &&... args) : t(std::forward<Args>(args)...) {}
};

We normally only care about the types of the arguments during the initialization of t, anyway.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 4
    Additional care might be done for copy constructor: `Bar(Bar&)` would match that template constructor instead of expected `Bar(const Bar&)`. – Jarod42 Jan 16 '20 at 09:30
  • In this case the `t(t(std::forward(args)...)` will fail if instantiate `Bar(Bar&)`, I think I can use the deduce trick, but it seems that the constructing of `t` is after when deduce is finished, so I can't play the deduce trick, any suggestions? –  Jan 16 '20 at 09:54
  • 1
    @ravenisadesk - I don't know what you mean by the "deduce trick", but there are workarounds. There's in fact a question devoted to that very problem https://stackoverflow.com/a/9288243/817643 – StoryTeller - Unslander Monica Jan 16 '20 at 10:48