1

I got a class uses template parameter pack:

template<typename ...Ts>
class Foo {
 public:
  Foo(Ts &&...ts) {
    // do something 
  }
};

then use it:

std::string s;
Foo<std::string> foo(s);

But this code failed to compile, the compiler seems accept r-values, not "universe references":

note: candidate constructor not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'std::__cxx11::basic_string<char> &&' for 1st argument

If I change to:

Foo<std::string> foo(std::move(s));

then it works.

but if I test with a template function:

template<typename ...Ts>
void Bar(Ts &&... ts) {
  // do something
}

and then use it:

Bar(s);

it works fine. So what do I miss?

1 Answers1

0

Note that forwarding reference must be function parameters of function templates,

1) function parameter of a function template declared as rvalue reference to cv-unqualified type template parameter of that same function template:

Foo::Foo is a non-template constructor, then ts is just declared as rvalue-reference.

You might want

template<typename ...Ts>
class Foo {
 public:
  template<typename ...Tf>
  Foo(Tf &&...ts) {
    // do something 
  }
};

Or you can make two overloaded constructors which taking lvalue-reference and rvalue-reference.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405