使用模板时可能是编译器中的 SFINAE 错误?
May be a SFINAE BUG in complier when use template?
我想用标准代码来编写像 std::is_union 这样的实用程序,我们知道类类型不能扩展联合类型,这是错误,所以像这样的一些代码
#include <iostream>
template<typename T>
class class_type_can_extends :public T{
public:
using type = void;
};
template<typename T,typename U = void>
struct is_not_union:std::false_type {
};
template<typename T>
struct is_not_union < T, std::void_t<typename class_type_can_extends <T>::type >> :std::true_type {
};
class c_data{
};
union u_data{
};
int main(){
/*#1*/ std::cout<< is_not_union<c_data>::value<<std::endl; /*print true*/
/*#2*/ std::cout<< is_not_union<u_data>::value<<std::endl; /*this code make
all complier error*/
}
G++ 打印错误:
main.cpp: In instantiation of ‘class class_type_can_extends<u_data>’:
main.cpp:26:43: recursively required by substitution of ‘template<class T> struct is_not_union<T, std::void_t<typename class_type_can_extends<T>::type> > [with T = u_data]’
main.cpp:26:43: required from here
main.cpp:3:7: error: base type ‘u_data’ fails to be a struct or class type
class class_type_can_extends :public T {
叮当打印错误:
main.cpp:3:38: error: unions cannot be base classes
class class_type_can_extends :public T {
~~~~~~~^
main.cpp:14:47: note: in instantiation of template class 'class_type_can_extends<u_data>' requested here
struct is_not_union < T, std::void_t<typename class_type_can_extends <T>::type >> :std::true_type {
^
main.cpp:26:23: note: during template argument deduction for class template partial specialization 'is_not_union<T,
std::void_t<typename class_type_can_extends<T>::type> >' [with T = u_data]
/*#2*/ std::cout << is_not_union<u_data>::value << std::endl; /*this code make
^
main.cpp:26:23: note: in instantiation of template class 'is_not_union<u_data, void>' requested here
1 error generated.
与:
错误 C2569
为什么 #2 代码会让编译器出错,编译器会在 #2 代码上使用 SFINAE 规则(将 T 替换为"u_data",然后失败(,并选择主模板?为什么 sfinae 在这里无效,可能是这里的错误?
来自 cpp首选项:
只有函数类型或其模板参数类型或其显式说明符(自 C++20 以来(的直接上下文中的类型和表达式中的失败才是 SFINAE 错误。如果对替换类型/表达式的计算导致副作用,例如实例化某些模板专用化、生成隐式定义的成员函数等,则这些副作用中的错误将被视为硬错误
SFINAE 适用于即时上下文,这里您有一个硬错误失败。
在typename class_type_can_extends<T>::type
中,SFINAE 适用于不存在type
,如果class_type_can_extends<T>
实例化失败,则不适用。
请注意,我们不能仅使用标准C++来区分union
和类类型 (不含std::is_union
(。大多数编译器为此提供了内部函数。
相关文章:
- C/C++编译器通常会删除重复的库吗
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- Win32编译器选项和内存分配
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++,我收到一个无法理解的编译器错误
- 在线编译器中的分段C++没有打印消息
- 为什么使用SFINAE而不是函数重载
- 如何使用模板函数的函数签名进行SFINAE
- 数据成员SFINAE的C++17测试:gcc vs clang
- 使用在用于SFINAE的void_t中具有参数的方法
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 使用模板时可能是编译器中的 SFINAE 错误?
- 带有VC++编译器的SFINAE
- 如何使用“英特尔C++编译器”(ICC)在三种方法上使用SFINAE
- SFINAE:编译器不选择专用模板类
- 是c++ (03) SFINAE方面编译器独立的
- SFINAE 尝试使用布尔值给出编译器错误:"模板参数'T::value'涉及模板参数"
- 为什么SFINAE导致编译器错误,它应该工作