Error using r and l value constructors in template class

I have a template template:

template <typename T> class MyClass { public: MyClass(const T & val); // First MyClass(T&& val); // Second }; 

Basically, I want MyClass to be a construct from T , whether it is rvalue or lvalue. Now that I have something like

 const A& foo = ...; MyClass<const A&> x(foo); 

I get an override error for MyClass(const A & val) .

I assume that this is because T && is a universal link and because of the rules for dropping links, the second constructor is also converted to the same signature as the first.

First, did I understand the error scenario correctly? secondly, how can I get around this problem (I want to use the optimization features that carry semantics when creating MyClass)?

+5
source share
1 answer

I assume this is because T && is a universal reference ...

Wrong. T&& not a universal (forwarding) link in this case. T&& is just the rvalue reference to T Universal / redirect links should be displayed.

... and because of the rules for collapsing links, the second constructor is also converted to the same signature as the first.

It is right. Our two designers accept:

 T const& ==> A const& const& ==> A const& T&& ==> A const& && ==> A const& 

hence the error of overriding.

Depending on what you want to do, only std::decay T might be a simple solution:

 template <typename T> class MyClass { using DecT = typename std::decay<T>::type; public: MyClass(const DecT& ); MyClass(DecT&& ); }; 

In your example, it will still create a class with two constructors: one takes const A& , and the other takes A&& .

+6
source

Source: https://habr.com/ru/post/1212475/


All Articles