【问题标题】:std::enable_if to filter out the argument with the type of char*std::enable_if 过滤掉 char* 类型的参数
【发布时间】:2021-03-25 19:25:14
【问题描述】:

为什么char* pstr="hello"; pushArg(pstr); 仍然调用这样的模板?

你看已经有&&(!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)
                               &&   std::is_pointer<T>::value
                               && (!std::is_same<std::string*, T>::value)
                               && (!std::is_same<char, typename std::remove_cv<std::remove_pointer<T>>>::value)
                               && (!std::is_same<unsigned char, typename std::remove_cv<std::remove_pointer<T>>>::value)
int pushArg(T& val)
{

}   

【问题讨论】:

  • char* pstr="hello"; 无法编译,缺少 const
  • @Jarod42 未启用 -Wall 或类似功能时的警告。

标签: c++ c++11 templates typetraits enable-if


【解决方案1】:

首先,您已使用 C++11 标记您的答案,但您使用 C++14 中的 std::remove_cv_t

在 C++17 中,您的函数如下所示:

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

如果通过char *pstr = "hello"会抛出错误。

在 C++11 中,您缺少 typename std::remove_cv&lt;typename std::remove_pointer&lt;T&gt;::type&gt;::type 部分。完整代码如下:

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

DEMO

【讨论】:

  • 额外的typename可以在你的C++17版本中删除(只需要T的那个)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多