I was reading the paper regarding template argument deduction for class templates here http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html. This feature is in the C++17 standard, and some things had confused me.
template <typename T>
class Something {
public:
// delete the copy and move constructors for simplicity
Something(const Something&) = delete;
Something(Something&&) = delete;
explicit Something(T&&) { ... }
explicit Something(const T&) { ... }
template <typename U, typename EnableIfNotT<U, T>* = nullptr>
Something(U&&) { ... }
};
Given the above code, if someone tries to instantiate an instance of the above template like this
auto something = Something{std::shared_ptr<int>{}};
will the rvalue reference overload always be called? Since the overload set considered for deduction is
template <typename T>
Something<T> F(T&&) { ... }
template <typename T>
Something<T> F(const T&) { ... }
template <typename T, typename U, typename EnableIfNotT<U, T>*>
Something<T> F(U&&) { ... }
- The second overload will never be preferred over the first one (since that is now a forwarding reference overload, instead of being an rvalue reference overload), so what is supposed to happen here?
- And it seems like the last one can never be called without explicitly specifying the
Tparameter, is this the intended behavior? - Also are there any other gotchas or style guidelines that one should keep in mind when using template argument deduction for class templates?
- Further are user defined deduction guides required to be after the class definition? For example, can you have the trailing return type in the declaration of the class constructor within the class definition itself? (Unlike the iterator constructor here http://en.cppreference.com/w/cpp/language/class_template_deduction)