为什么我们不能直接使用类模板来推导方法模板?荸荠属
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;
}
但是我想了解为什么我需要为间接模板扣除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编程的原因。
相关文章:
- 为什么我们不能直接使用类模板来推导方法模板?荸荠属
- 为什么我们需要常量方法?
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- 我们如何从 C# 中的 DLL 中获取C++所有方法?
- 为什么我们不能同时实现两个方法'getAB() &&'和'getAB()'?
- 当我们在MSDN中调用UpdateWindows()时,该方法是什么
- 我们可以在 caa 的构建图方法中只使用初始状态和空状态吗?
- 为什么我们选择"bounding box"方法来填充三角形?
- 我们需要对一个只有read方法的类进行线程安全设计吗
- 我们还能使用任何其他方法来访问Android中的C 代码,而不是使用JNI访问C 代码
- 对于良好的编码实践,如果我们已经在方法1中验证并且方法1将数据传递给方法2,我们是否仍然需要在方法2中再次验证数据?
- 我们可以将所有"int"参数和返回类型替换为 DllImport 方法签名中的"IntPtr"吗?
- 我们可以在C文件中定义一个C++方法吗
- 我们可以通过在C++中的类中使用关键字“abstract”使所有方法抽象来声明接口类吗
- 我们是否有更好的方法来返回C++中的抽象类
- 当我们不关心返回值时,在 c++ 的代码片段中只调用一次函数的更好方法?
- 为什么我们在C++的单例模式中使用静态方法和静态函数
- 我们可以动态链接 DLL 的不同方法是什么
- 我们应该在Qt中使用哪种内存管理方法
- 我们可以重载在子类中被覆盖的方法吗?