How one can use universal reverence in constructor in a templated class with type deduction. I tried all the options and nothing worked.
Consider example:
#include <vector>
template<class T> struct A {
A(T&& a) { }
};
template<class T> struct B {
B(T& a) { }
};
template<class T> struct C {
template<class T2> C(T2&& a) {}
};
template<class T> void foo(T&& a) { }
auto get_r_value() {
return std::vector<int>(100);
}
std::vector<int>& get_l_value() {
static std::vector<int> v(100);
return v;
}
int main() {
foo(get_r_value()); // ok
foo(get_l_value()); // ok
A a1(get_l_value()); // error!
A a2(get_r_value()); // ok
B b1(get_l_value()); // ok
B b2(get_r_value()); // error!
C c1(get_l_value()); // error!
C c2(get_r_value()); // error!
}
If you really want to use a universal reference, you have to go with struct C
, because in A
you actually declare a rvalue reference, not a forwarding (universal) reference.
You can fix the deduction of C
with a user defined deduction guide
template <typename T>
C(T&&) -> C<std::remove_cvref_t<T>>;
Note that deduction guides require C++17