Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

combining two constructors that copy and move

Currently, one of my toy class templates has two constructors that look very similar:

optional(const T& x)
{
    construct(x);
}

optional(T&& x)
{
    construct(std::move(x));
}

Can I combine them into a single constructor template, or will this change the semantics somehow?

template<typename U>
optional(U&& x)
{
    construct(std::forward<U>(x));
}
like image 634
fredoverflow Avatar asked Sep 12 '11 13:09

fredoverflow


2 Answers

A templated constructor will never be (considered by the compiler to be) a copy constructor, sorry.

like image 125
Cheers and hth. - Alf Avatar answered Oct 24 '22 18:10

Cheers and hth. - Alf


It changes the way traits such as std::is_constructible and std::is_convertible interact with optional. For example given:

class A {};

int main()
{
    std::cout << std::is_constructible<optional<A>, int>::value << '\n';
};

Your original code would print out:

0

But your new code will print out:

1

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.

like image 26
Howard Hinnant Avatar answered Oct 24 '22 17:10

Howard Hinnant