template <typename T> Variant(const T&)
Calling (a) does not require any conversion; argument type DerivedVariantB , is an exact match, where T = DerivedVariantB .
A derivative conversion is required for invocation (b) . Therefore, (a) goes better with (b) .
If you call a constructor with an argument of type CustomVariant , both constructors are exact matches, so (b) is selected because, when everything else is equal, a template is preferable to a template.
You can suppress the use of a pattern where T obtained from Variant with std::enable_if :
template<typename T> Variant(const T&, typename std::enable_if< !std::is_base_of<Variant, T>::value, void* >::type = 0) { std::cout << "template" << std::endl; }
This makes the template incompatible when T obtained from Variant , so it will not be available during overload resolution. enable_if and is_base_of are new to C ++ in C ++ 0x, and your compiler and standard library can support them. If not, you can also find them in C ++ TR1 or Boost.TypeTraits .
source share