为什么我们不能直接使用类模板来推导方法模板?荸荠属

Why can't we use class templates directly for deducing method templates? SFINAE

本文关键字:方法 我们 为什么 不能      更新时间:2023-10-16

这段代码有效:

// 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;
}

但是我想了解为什么我需要为间接模板扣除template <class S = T, class = decltype(S())>设置S

我宁愿通过使用template <class = decltype(T())>来更简单地做到这一点,但在 gcc 中这会导致错误的输出:所有对Test方法的调用都转到第一个;在 clang 中,这会导致错误call to deleted constructor of 'NoDefaultConstructor'(感谢 HolyBlackCat 在这里指出 clang 编译错误(。

为什么?编译器/c ++标准迫使我们间接引用类模板的过程是什么?

这是因为您首先实例化模板类Tester。因此,需求class = decltype(T())成为模板类Tester<T>本身的要求。因此,如果不满意,则模板类的格式不正确。编辑:想象一下 ypu 实际上想编写一个以X作为模板参数并使用class X = decltype(T())作为默认条目的模板函数?编译器如何区分它与SFINAE的东西?

间接推导template <class S = T, class = decltype(S())>将其转换为对模板函数的要求Test而不是整个类。

这是技术原因。是的,没有人喜欢SFINEA和函数元编程,这就是为什么在C++20中引入概念并开发ConstexPR编程的原因。

相关文章: