gpt4 book ai didi

c++ - 使用模板时可能是编译器中的 SFINAE BUG?

转载 作者:行者123 更新时间:2023-11-30 04:43:14 26 4
gpt4 key购买 nike

我想使用标准代码来编写像 std::is_union 这样的实用程序,我们知道类类型不能扩展 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 {

clang 打印错误:

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.

对比:

error C2569

为什么 #2 代码会导致编译器错误,编译器会在 #2 代码上使用 SFINAE 规则(将 T 替换为“u_data”,然后失败),并选择主模板?为什么 sfinae 在这里无效,可能是一个错误在这里?

最佳答案

来自 cppreference :

Only the failures in the types and expressions in the immediate context of the function type or its template parameter types or its explicit specifier (since C++20) are SFINAE errors. If the evaluation of a substituted type/expression causes a side-effect such as instantiation of some template specialization, generation of an implicitly-defined member function, etc, errors in those side-effects are treated as hard errors

SFINAE 适用于直接上下文,这里是硬错误失败。

typename class_type_can_extends<T>::type , SFINAE 适用于 type不存在,如果 class_type_can_extends<T> 的实例化则不存在失败。

请注意,我们无法区分 union和仅使用标准 C++ 的类类型(没有 std::is_union )。大多数编译器为此提供内在函数。

关于c++ - 使用模板时可能是编译器中的 SFINAE BUG?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58386940/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com