This is a classical case for SFINAE and enable_if
.
In another answer, Potatoswatter has already posted a type trait is_default_constructible
that can be reused here:
void createObj(
typename enable_if_c<is_default_constructible<C>::value, void>::type* dummy = 0)
{
C* objPtr = new C();
}
void createObj(
typename disable_if_c<is_default_constructible<C>::value, void>::type* dummy = 0)
{
C* objPtr = 0;
}
Or, if your function has a non-void return type T
(thanks to DeadMG) you can omit the dummy default argument:
typename enable_if_c<is_default_constructible<C>::value, T>::type createObj()
{
C* objPtr = new C();
}
typename disable_if_c<is_default_constructible<C>::value, T>::type createObj()
{
C* objPtr = 0;
}
SFINAE means that a template which cannot be instantiated for a given type, will not. enable_if_c
basically results in a valid type if and only if its argument is true
. Now we use the metafunction is_default_constructible
to test whether the type C
has a default constructor. If so, enable_if_c<…>::type
will result in a valid type, otherwise it will not.
The C++ compiler will thus only see one of the two functions, to wit the one that is usable in your context. See the documentation of enable_if
for more details.