Reputation: 16711
I tried to make default constructor = default;
conditionally depending on class template argument's property using following technique:
#include <type_traits>
#include <utility>
#include <iostream>
#include <cstdlib>
template< typename T >
struct identity
{
};
template< typename T >
struct has_property
: std::false_type
{
};
template< typename T >
struct S
{
template< typename X = T,
typename = std::enable_if_t< !has_property< X >::value > >
S(identity< X > = {})
{ std::cout << __PRETTY_FUNCTION__ << std::endl; }
template< typename X = T,
typename = std::enable_if_t< has_property< X >::value > >
#if 0
S() = default;
#else
S()
{ std::cout << __PRETTY_FUNCTION__ << std::endl; }
#endif
};
struct A {};
struct B {};
template<>
struct has_property< B >
: std::true_type
{
};
int main()
{
S< A >{};
S< B >{};
return EXIT_SUCCESS;
}
But for #if 1
it gives an error:
main.cpp:32:11: error: only special member functions may be defaulted
S() = default;
^
Is not template< ... > S()
a declaration of a default constructor for S
?
Can I implement such a dispatching using coming Concepts in future?
Upvotes: 3
Views: 219
Reputation: 141554
I think this is covered by [dcl.fct.def.default]:
A function that is explicitly defaulted shall:
- be a special member function,
- have the same declared function type (except for possibly differing ref-qualifiers and except that in the case of a copy constructor or copy assignment operator, the parameter type may be “reference to non-const T”, where T is the name of the member function’s class) as if it had been implicitly declared,
In your case, the implicitly-declared default constructor would not have been a function template, so you cannot explicitly default it.
GCC 5.x gives the error for your code, error: a template cannot be defaulted
.
Upvotes: 2