1

Consider the simple code (Disclaimer: This is a noobie question) :

template<typename T> struct foo
{
foo(const T&);
foo(T&& ctorArguement):ptrToSomeType(new someType(std::forward<T&&>(ctorArguement))){}
                                                                ^^
std::unique_ptr<someType> ptrToSomeType;
}

compared to this :

template<typename T> struct foo
{
foo(const T&);
foo(T&& ctorArguement):ptrToSomeType(new someType(std::forward<T>(ctorArguement))){}
                                                               ^^
std::unique_ptr<someType> ptrToSomeType;
}

I think I should have used std::move but I was wondering particularly about these two cases. So are two version completely equal, or one is better than another?.

Angelus Mortis
  • 1,534
  • 11
  • 25
  • 5
    None of them are at all appropriate. You want `forward` when the parameter is a deduced `T&&`, and you want `move` when the parameter binds an rvalue. – Kerrek SB Mar 10 '16 at 19:39
  • @KerrekSB But will those above code work, considering the constructor is rvalue? Thanks – Angelus Mortis Mar 10 '16 at 19:44
  • Possible Duplicate: [When to use std::forward to forward arguments?](http://stackoverflow.com/questions/7257144/when-to-use-stdforward-to-forward-arguments) – NathanOliver Mar 10 '16 at 19:46
  • It must be embarrassing for you all C++ pros to answer such question? :p :D – Angelus Mortis Mar 10 '16 at 19:49

1 Answers1

7

Those two code snippets do the same thing. The first one casts to T&& &&, which is T&&. The second one casts to T&&. Using std::move would have the same effect.

To avoid confusing readers of the code (this includes yourself), you should use std::move in this context. std::forward<T> is only supposed to be used when the T is deduced from a forwarding reference T&&, and that's not the case in your code since the T is actually a parameter for the enclosing class, not the function. As for std::forward<T&&>, it does the same thing as std::forward<T> when the latter is applicable, but this is not at all obvious, so it will also confuse readers.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • *"Using std::move would have the same effect."*, not necessarily true if (for some reason) `T` is an lvalue reference type, then `std::forward` is more appropriate – Piotr Skotnicki Mar 10 '16 at 20:00
  • 2
    @PiotrSkotnicki If `T` is an lvalue reference type, the whole class is ill-formed since both overloads would reduce to taking the same argument. So whole thing is moot. – Barry Mar 10 '16 at 20:03
  • @Barry "both overloads would reduce to taking the same argument" how is that? pleaseeee explain ? Thanks – Angelus Mortis Mar 10 '16 at 20:05