Может быть SFINAE ошибка в компиляторе при использовании шаблона? - PullRequest
1 голос
/ 15 октября 2019

Я хочу использовать стандартный код для написания утилит, таких как 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 { 

ошибка печати 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.

vs:

ошибка C2569

почему код # 2 делаетошибка компилятора. Компилятор будет использовать правила SFINAE для кода # 2 (заменив T на «u_data», затем Failed) и выбрать основной шаблон. Почему sfinae здесь неэффективен, здесь может быть ошибка?

1 Ответ

1 голос
/ 15 октября 2019

С cppreference :

Только сбои в типах и выражениях в непосредственном контексте типа функции или ее типов параметров шаблона или его явного спецификатора (так как C ++20) СФИНАЕ ошибки. Если оценка замещенного типа / выражения вызывает побочный эффект, такой как создание некоторой специализации шаблона, создание неявно определенной функции-члена и т. Д., Ошибки в этих побочных эффектах рассматриваются как серьезные ошибки

SFINAE применяется к непосредственному контексту, здесь возникает серьезная ошибка.

В typename class_type_can_extends<T>::type SFINAE применяется, если type не существует, а не в случае сбоя создания экземпляра class_type_can_extends<T>.

Обратите внимание, что мы не можем различить union и типы классов, используя только стандартный C ++ (без std::is_union). Большинство компиляторов предоставляют встроенные функции для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...