If this is undesirable, and you still want to go with your new code, you could enable_if it to restrict U to acceptable types.

The only other possible issue I see is if T can be a reference type (e.g. int&). In that case the second constructor of your original code looks suspicious as it would be passing in an rvalue, and you might be trying to bind that rvalue to a non-const lvalue reference (can't tell for sure). If T can never be a reference type, no need to worry about this.

Erm, optional(const T&) is not even a copy constructor, what was I thinking? edited
–
fredoverflowSep 12 '11 at 13:22

@Fred: in that case, consider using C++11 constructor forwarding? if it's implemented by compiler yet. i don't know which compilers support it, if any. alternatively, if not supported, you can use an artificial base class. forward the constructor calls up to base class.
–
Cheers and hth. - AlfSep 12 '11 at 13:26

Oh, construct is not a constructor, it's member function template.
–
fredoverflowSep 12 '11 at 13:31

With that perfect forwarding constructor template though, you will get problems with optional<int> x, y(x);. This would call the perfect-forwarding constructor template to do the copy, which is presumably not what you want. So you need some SFINAE there to disable it if remove_reference<U>::type is cv optional<T>
–
Johannes Schaub - litbSep 14 '11 at 20:07

Then possibly the semantics are different. Your original overload set passes either an lvalue reference to const or an rvalue reference to non-const. The template version can pass an lvalue reference to non-const as well. (I'm ignoring rvalue references to const.)

In all likeliness though construct is either declared to accept U&& (else your previous overload that moves a T wouldn't work) and in this case should deal with non-const lvalues, or is declared to accept U const& and in this case it's harmless.