This code works:
// g++ -std=c++11
// (or)
// clang++ -std=c++11
#include <iostream>
template <class T>
struct Tester
{
template <class S = T, class = decltype(S())>
static void Test (int && k)
{
std::cout << "Default constructible" << std::endl;
}
static void Test (...)
{
std::cout << "Not default constructible" << std::endl;
}
};
struct HasDefaultConstructor
{
HasDefaultConstructor() = default;
};
struct NoDefaultConstructor
{
NoDefaultConstructor() = delete;
};
int main ()
{
Tester<HasDefaultConstructor>::Test(int());
Tester<NoDefaultConstructor>::Test(int());
return 0;
}
But I'd like to understand why I need to set up S
for the indirect template deduction template <class S = T, class = decltype(S())>
.
I'd prefer to do it more simply by using template <class = decltype(T())>
, but in gcc this results in wrong outputs: all calls to the Test
method go to the first one; and in clang this results in an error call to deleted constructor of 'NoDefaultConstructor'
(Thanks to HolyBlackCat for pointing out the clang compile error here).
Why? What is the process of the compiler / c++ standard that forces us to indirectly refer to the class templates?