代码之家  ›  专栏  ›  技术社区  ›  xmh0511

使用模板时可能是编译器中的SFINAE错误?

  •  0
  • xmh0511  · 技术社区  · 5 年前

    我想用标准代码来编写像std::is\u union这样的utils,我们知道类类型不能扩展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

    0 回复  |  直到 5 年前
        1
  •  1
  •   Jarod42    5 年前

    cppreference :

    只有函数类型或其模板参数类型或其显式说明符(或C++ 20)的上下文中的类型和表达式中的错误是sFANE错误。如果对替换类型/表达式的求值导致副作用,例如实例化某些模板专门化、生成隐式定义的成员函数等,则这些副作用中的错误将被视为硬错误

    SFINAE应用于即时上下文,这里有一个硬错误失败。

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

    请注意,我们无法区分 union (无 std::is_union