1

I'm trying to check if a default constructor exists for a template argument. I want to do something like this:

template <typename A>
class Blah
{
   Blah() { A* = new A(); } 
}

But i want to detect at compile time via SFINAE or some other trick if that constructor exists, and raise a static_assert of my own if it doesn't.

The problem arises when i have classes (like std::vector) that dont have a "default constructor" but a constructor with default parameters.

So using std::has_trivial_default_constructor won't return true. Although i can use new vector<T>().

David Hammen
  • 32,454
  • 9
  • 60
  • 108
Yochai Timmer
  • 48,127
  • 24
  • 147
  • 185
  • 3
    Won't `std::is_default_constructible` still work then? – chris Dec 09 '12 at 10:09
  • Doesn't exist in VS2010 ... And besides it's defined to return true if there's a default constructor. Which vector for example doesn't have, but can be constructed with no parameters. – Yochai Timmer Dec 09 '12 at 10:12
  • 6
    Having all default parameters still makes it a default constructor. GCC 4.7.2 says `std::vector` [is default-constructible](http://stacked-crooked.com/view?id=a6167e3bfe0de00a7f185086818b0aee). – chris Dec 09 '12 at 10:14

2 Answers2

6

Here's a possible implementation of the type trait:

template<typename T>
class is_default_constructible {

    typedef char yes;
    typedef struct { char arr[2]; } no;

    template<typename U>
    static decltype(U(), yes()) test(int);

    template<typename>
    static no test(...);

public:

    static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

struct foo {
    foo(int) {}
};

int main()
{
    std::cout << is_default_constructible<foo>::value << '\n'        // 0
              << is_default_constructible<std::vector<int>>::value;  // 1
}
jrok
  • 54,456
  • 9
  • 109
  • 141
4

There is no std::has_trivial_default_constructor in the C++ standard; this appears to be a gcc enhancement that came from Boost. This is not what you want. You don't want to check if something has a trivial default constructor; you want to check if some class has a default constructor, trivial or not. Use std::is_default_constructible (assuming a c++11 compliant-compiler).

David Hammen
  • 32,454
  • 9
  • 60
  • 108