为什么推导方法模板不能直接使用class个模板呢? SFINAE
Why can't we use class templates directly for deducing method templates? SFINAE
此代码有效:
// 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 编译错误)。
为什么?强制我们间接引用 class 模板的编译器/c++ 标准的过程是什么?
这是因为您首先实例化了模板classTester
。因此,要求 class = decltype(T())
成为对模板 class Tester<T>
本身的要求。因此,如果不满足,则模板 class 格式错误。 编辑:想象一下ypu实际上想写一个模板函数,以X
作为模板参数并使用class X = decltype(T())
作为默认条目?编译器如何区分它和 SFINAE 的东西?
间接推导template <class S = T, class = decltype(S())>
将其转化为对模板函数Test
的要求,而不是整个class.
这是技术原因。是的,没有人喜欢 SFINEA 和函数元编程,这就是为什么在 C++20 中引入概念并开发 constexpr 编程的原因。
此代码有效:
// 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 编译错误)。
为什么?强制我们间接引用 class 模板的编译器/c++ 标准的过程是什么?
这是因为您首先实例化了模板classTester
。因此,要求 class = decltype(T())
成为对模板 class Tester<T>
本身的要求。因此,如果不满足,则模板 class 格式错误。 编辑:想象一下ypu实际上想写一个模板函数,以X
作为模板参数并使用class X = decltype(T())
作为默认条目?编译器如何区分它和 SFINAE 的东西?
间接推导template <class S = T, class = decltype(S())>
将其转化为对模板函数Test
的要求,而不是整个class.
这是技术原因。是的,没有人喜欢 SFINEA 和函数元编程,这就是为什么在 C++20 中引入概念并开发 constexpr 编程的原因。