Search code examples
c++perfect-forwarding

How do I perfect forward as generically as possible?


I have this example:

template<class ValueType>
class MyTemplateClass
{
public:
    MyTemplateClass(ValueType&& Value) : MyMemberVar{ std::forward<ValueType>(Value) } {}
    
private:
    ValueType MyMemberVar;
};

int main()
{
    int x{ 5 };
    MyTemplateClass<int> Instance{ x };
    
    return 0;
}

This code does not compile, with: error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'.

I understand the error. A fix would be to give it an rvalue like so:

MyTemplateClass<int> Instance{ 5 };

But this isn't very usable. I could also give it a more specific type:

MyTemplateClass<const int&> Instance{ x };

But I feel like this could be better. For instance, std::vector can do:

int x = 5;
std::vector<int>{ x, x, x };

This works just fine... how does std::vector accomplish this? Is there something wrong with my code?

Thank you.


Solution

  • Is there something wrong with my code?

    Yes.


    The constructor you have written:

    MyTemplateClass(ValueType&& Value);
    

    Value is not a forwarding reference here, it is just an rvalue reference. To make it a forwarding reference, the type of Value must be a template parameter of this particular function:

    template<typename T>
    MyTemplateClass(T&& Value) : MyMemberVar{ std::forward<T>(Value) } {}
    

    Demo