I simplified my class MyVector in C++ by combining the lvalue and rvalue constructors into a single universal reference constructor. However, this change has led to a problem: the template parameter T of my class cannot be deduced from the universal reference parameter U in the constructor.
Here’s the definition of my class:
template<typename T> class MyVector { public: std::vector<T> data; ... template<typename U> MyVector(U&& data) : data(std::forward<U>(data)) {} }; The consequence of this limitation is that using my class becomes inconvenient. Instead of being able to instantiate it like this:
MyVector v = std::vector<int>({1, 2, 3}); I am forced to specify the template parameter explicitly:
MyVector<int> v = std::vector<int>({1, 2, 3}); Problem:
I would like to enforce that std::decay_t<U> must be a std::vector<T> and, in turn, deduce T from U. It’s important to note that I do not want to simply ignore the definition of this constructor if std::decay_t<U> != std::vector<T>, which I could achieve using std::enable_if. Instead, I want to bind std::decay_t<U> to std::vector<T> in a way that enforces equality between these types, allowing type deduction to take place. Is there a way to achieve this in C++ using type traits or other techniques?
What I have tried:
I tried to solve this problem by creating a method bind in the class MyVector that takes one parameter of type std::vector<T> and passing std::declval<std::decay_t<U>>() to this function. Unfortunately, this failed with an error indicating that the result of std::declval must be unused. I have no other ideas on how to bind U to std::vector<T> in a way that would allow for type deduction. Is there a way to achieve this in C++ using type traits or other techniques?
std::decay_t<U> != std::vector<T>" and "I want to bindstd::decay_t<U>tostd::vector<T>in a way that enforces equality between these types" I need to admit that I don't understand the problem. These two sentences seem to contradict each other in my opinion. Cound you add some examples of initialization and describe what should be the outcome. Would user-defined deduction guides work for you? Live demo: godbolt.org/z/nrEfMGhs4MyVector(std::vector<T> data) : data(std::move(data)) {}