此代码有效:
// 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;
}
但是我想了解为什么我需要为间接模板推导S
设置template <class S = T, class = decltype(S())>
。
我希望使用template <class = decltype(T())>
更简单地执行此操作,但是在gcc中,这会导致错误的输出:对Test
方法的所有调用都转到第一个;并在clang中导致错误call to deleted constructor of 'NoDefaultConstructor'
(感谢HolyBlackCat在此处指出clang编译错误)。
为什么?强制我们间接引用类模板的编译器/ c ++标准的过程是什么?
这是因为您首先实例化模板类Tester
。因此,要求class = decltype(T())
成为模板类Tester<T>
本身的要求。因此,如果不满意,则模板类格式错误。
间接推导template <class S = T, class = decltype(S())>
将其转换为模板函数Test
的需求,而不是整个类。