Home > Blockchain >  How do I perfect forward as generically as possible?
How do I perfect forward as generically as possible?

Time:12-03

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.

CodePudding user response:

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

  • Related