convert() utility functionA few recent threads have expected either return ptr;
    (Bjarne Stroustrup in c++std-ext-14038) or
    foo({ptr}) (https://groups.google.com/a/isocpp.org/d/topic/std-proposals/YBnWHvd_dIY/discussion)
    to invoke the explicit unique_ptr(T*) constructor.  Both
    threads eventually proposed a list of language changes to make the necessary
    conversion more concise:
auto{ptr}explicit listinit unique_ptr(pointer
      p) to allow {ptr} to work.return explicit({ new foo });auto return ptr;explicit return x or return explicit xreturn statement. (By analogy to the rule for move constructors.)In c++std-ext-14049 and independently in https://groups.google.com/a/isocpp.org/d/msg/std-proposals/YBnWHvd_dIY/2iBLM-fAqngJ, I and Vicente J. Botet Escriba proposed a library solution to handle this problem with a single extra token:
template<typename T>
struct Converter {
  T source_;
  Converter(T source) : source_(std::forward<T>(source)) {}
  template<typename U, decltype(static_cast<U>(std::forward<T>(source_)), 1)=0>
  /*implicit*/ operator U() {
    return static_cast<U>(std::forward<T>(source_));
  }
};
template<typename T>
Converter<T> convert(T&& source) {
  return Converter<T>(std::forward<T>(source));
}Where an explicit conversion is desired, the user needs to write
    convert(ptr) in a context that expects a particular type.
It's worth calling out some features of this implementation:
convert() uses a T&& parameter to deduce the
      rvalue/const-ness of the argument, and then saves that exact type into the
      returned Converter object.  This allows the
      Converter to perfectly forward the argument into the target
      explicit conversion.The Converter object appears
      to store the source object by value, but
      because the deduced parameter is passed in, it actually adapts to the
      exact type of the argument.  If the argument was an lvalue reference,
      source_ is an lvalue reference to convert()'s
      argument.  If the argument was an rvalue reference or temporary, it's
      moved into the Converter, and then moved again into the
      explicit conversion.  Implementations can optimize this into a single move
      by specializing Converter separately for lvalue and rvalue
      arguments.  Trying to capture an rvalue reference directly would make
auto c = convert(Temporary());unsafe.
The implicit conversion operator is removed from the overload set if there's no explicit conversion to the requested type. This allows overload resolution to work as expected:
struct Explicit {};
struct Unrelated{};
struct Source {
  explicit operator Explicit() const;
};
void overloaded(Explicit);
void overloaded(Unrelated);
void test() {
  overloaded(convert(Source()));  // Selects overloaded(Explicit).
}tuple<>'s constructor, but LWG Issue
      2051 proposes fixing that problem by making tuple<>'s
      constructor implicit, and I don't know of many other use cases.  Further,
      convert(arg1, arg2, arg3) is more different from {arg1,
      arg2, arg3} than convert(arg) is from
      arg.  Therefore, I leave this possibility to a future
      extension.The example from c++std-ext-14038 is easily handled:
unique_ptr<Shape> read_shape(int i)
{
  switch(i) {
  case 1: return unique_ptr<Shape>(new Circle);
  case 2: return convert(new Triangle);
  }
}The proposed std::split()
    function yields another use case.  We'd like the returned range to be less
    magic, so it's likely to be a simple range of std::string_ref,
    which is only explicitly convertible to std::string.  If users
    want to initialize a vector<string> from a
    split() call, and we adopt a range library like Boost.Range, the constructors
    from N3456,
    and generic
    lambdas, they'd write something like:
std::vector<std::string> v =
    std::split(input) | transformed([](auto s) std::string(s));This isn't too bad, but convert() helps us shorten it for
    everything after the first use:
auto converted = transformed([](auto v) std::convert(v));  // Define once, globally.
std::vector<std::string> v = std::split(input) | converted;Wording is relative to N3485.
// [utility.convert] convert:
template <class T> see below convert(T&& source);template <class T> see below convert(T&& source);Requires: If T&& is an rvalue reference type, T shall be MoveConstructible ([moveconstructible]).
Returns: An object with a member of type T that is
      constructed from forward<T>(source).  For exposition only,
      this member is named source_.  [ Note: This
      member has reference type if source was passed an lvalue.  It
      only implies a move if source was passed an rvalue. -- end
      note ]
Remarks:
T is either implicitly or explicitly convertible
        to.U shall be implemented
        equivalently to
        static_cast<U>(std::forward<T>(source_)).CopyConstructible if
        either T is an lvalue reference type or T is
        CopyConstructible.