【问题标题】:How do I write a "pointer to const" type trait?如何编写“指向 const 的指针”类型特征?
【发布时间】:2016-05-22 03:34:12
【问题描述】:

我正在寻找以下结果:

/* true */  std::cout << ptr_to_const_v<const int*> << '\n';
/* true */  std::cout << ptr_to_const_v<const int*const> << '\n';
/* false */ std::cout << ptr_to_const_v<int*> << '\n';
/* false */ std::cout << ptr_to_const_v<int*const> << '\n';

这是我对类型特征的尝试:

template <typename T>
struct ptr_to_const : std::is_const<std::remove_pointer<T>> {};

这给出了所有 false。

或者,

template <typename T>
struct ptr_to_const : std::is_const<const std::remove_pointer<T>> {};

这给出了所有true。

我想这是因为 const 是类型的限定符,而不是类型本身的一部分。
我能做什么?

【问题讨论】:

  • 您希望从ptr_to_const&lt;char&gt;::value 得到什么?

标签: c++ templates constants typetraits c++17


【解决方案1】:

您正在检查 std::remove_pointer 类型特征的类型,而不是应用了该特征的类型。

C++14:

template <typename T>
struct ptr_to_const : std::is_const<std::remove_pointer_t<T>> {};
                                                       ^^

老年人:

template <typename T>
struct ptr_to_const : std::is_const<typename std::remove_pointer<T>::type> {};
                                    ^^^^^^^^^                      ^^^^^^

但是,由于您只是删除了指针,因此您无法判断 T 最初是否是指针,从而使 trait 过于宽松。既然你标记了这个C++1z,你可以使用std::conjunction,这基本上是一个短路元编程&amp;&amp;:

template <typename T>
struct ptr_to_const : std::conjunction<
    std::is_pointer<T>, 
    std::is_const<std::remove_pointer_t<T>>
> {};

您也可以选择 C++1z bool_constant 并使用 &amp;&amp;,尽管这不会造成短路。

【讨论】:

  • 请注意,这也适用于不是指针的 const 类型,因为如果 T 不是指针,std::remove_pointer&lt;T&gt; 会生成 T。
  • @BenjaminLindley,我刚刚注意到 :)
【解决方案2】:
template<class T>
using ptr_to_const = std::conjunction<std::is_pointer<T>, 
                                      std::is_const<std::remove_pointer_t<T>>>;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多