struct X
{
X(X&); // (1)
X(X&&); // (2)
X(const X&); // (3)
X(const X&&); // (4)
};
Consider the set U of all possible usages of X
where one of these four constructors will be bound and dispatched.
For example one element of U is:
int main()
{
X x1 = ...;
X x2(x1); // <-- (1) used
}
Now imagine we add a fifth constructor as follows:
struct X
{
X(X&); // (1)
X(X&&); // (2)
X(const X&); // (3)
X(const X&&); // (4)
template<class T> X(T&&); // (5)
};
Are there any new overload resolutions where one of the elements of U will now dispatch to (5)
as a better match instead of (1)
, (2)
, (3)
or (4)
as it previously did?
Consider derived classes:
struct Y : X
{ Y() { } };
int main()
{
Y y;
X x1(y); // derived class
}
Ok, I get it now. I guess, the case would be for any T convertible to X. For instance:
struct R
{
operator X() const;
};
int main()
{
R r{};
X x{r};
}
If your goal is to have one template constructor that handles only your (1) to (4) but nothing else you have to "SFINAE away" the others by something like:
template <typename T, typename U>
constexpr bool IsSame() {
return is_same<
typename decay<T>::type,
typename decay<U>::type
>::value;
}
struct X
{
template <class T, typename enable_if<IsSame<T, X>()>::type* = 0>
X(T&&);
};
Alternatively, if your goal is to tell apart T's convertible to X from the other T's, consider the following solution:
struct X
{
template <
class T,
typename enable_if<is_convertible<T, X>::value>::type* = 0
>
X(T&&); // do something
template <
class T,
typename enable_if<!is_convertible<T, X>::value>::type* = 0
>
X(T&&); // do something else
};
int main()
{
X x2(12); // <-- (5) used
}
(T is deduced to be int)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.