std::enable_if для фильтрации аргумента с типом char*

#c #c 11 #templates #typetraits #enable-if

#c #c 11 #шаблоны #typetraits #включить-если

Вопрос:

Зачем char* pstr="hello"; pushArg(pstr); все еще вызывать такой шаблон?

Вы видите amp;amp;(!std::is_same<char, typename std::remove_cv_t<std::remove_pointer_t<T>>>::value) , что он уже есть.

 template <typename T, 
          typename std::enable_if<(!std::is_same<lua_CFunction, T*>::value)
                               amp;amp;   std::is_pointer<T>::value
                               amp;amp; (!std::is_same<std::string*, T>::value)
                               amp;amp; (!std::is_same<char, typename std::remove_cv<std::remove_pointer<T>>>::value)
                               amp;amp; (!std::is_same<unsigned char, typename std::remove_cv<std::remove_pointer<T>>>::value)
int pushArg(Tamp; val)
{

}   
 

Комментарии:

1. char* pstr="hello"; не будет компилироваться, отсутствует const .

2. @Jarod42 Это предупреждение, когда -Wall или подобное не включено.

Ответ №1:

Во-первых, вы отметили свой ответ с C 11 помощью, но вы используете std::remove_cv_t из C 14.

В C 17 ваша функция будет выглядеть следующим образом:

 template <typename T, 
          std::enable_if_t<
            std::is_pointer_v< T >
            amp;amp; !std::is_same_v< std::string* , T >
            amp;amp; !std::is_same_v< char         , typename std::remove_cv_t<std::remove_pointer_t<T>> >
            amp;amp; !std::is_same_v< unsigned char, typename std::remove_cv_t<std::remove_pointer_t<T>> >,
            void
          >* = nullptr
         >
int pushArg(Tamp; val) {
    return 0;
} 
 

и в случае передачи будет выдана ошибка char *pstr = "hello" .

И в C 11 вам не хватает typename std::remove_cv<typename std::remove_pointer<T>::type>::type части. Полный код ниже:

 template <typename T, 
          typename std::enable_if<
            std::is_pointer< T >::value
            amp;amp; !std::is_same< std::string* , T >::value
            amp;amp; !std::is_same< char         , typename std::remove_cv<typename std::remove_pointer<T>::type>::type >::value
            amp;amp; !std::is_same< unsigned char, typename std::remove_cv<typename std::remove_pointer<T>::type>::type >::value,
            void
          >::type* = nullptr
         >
int pushArg(Tamp; val) {
    return 0;
}
 

ДЕМОНСТРАЦИЯ

Комментарии:

1. дополнительные typename могут быть удалены в вашей версии C 17 (требуется только один для T )