如何编写“指向 const 的指针”类型特征?

Tre*_*key 1 c++ templates constants type-traits c++17

我正在寻找以下结果:

/* 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';
Run Code Online (Sandbox Code Playgroud)

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

template <typename T>
struct ptr_to_const : std::is_const<std::remove_pointer<T>> {};
Run Code Online (Sandbox Code Playgroud)

这给出了所有false。

或者,

template <typename T>
struct ptr_to_const : std::is_const<const std::remove_pointer<T>> {};
Run Code Online (Sandbox Code Playgroud)

这给出了所有true。

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

chr*_*ris 5

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

C++14:

template <typename T>
struct ptr_to_const : std::is_const<std::remove_pointer_t<T>> {};
                                                       ^^
Run Code Online (Sandbox Code Playgroud)

较旧:

template <typename T>
struct ptr_to_const : std::is_const<typename std::remove_pointer<T>::type> {};
                                    ^^^^^^^^^                      ^^^^^^
Run Code Online (Sandbox Code Playgroud)

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

template <typename T>
struct ptr_to_const : std::conjunction<
    std::is_pointer<T>, 
    std::is_const<std::remove_pointer_t<T>>
> {};
Run Code Online (Sandbox Code Playgroud)

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

  • 请注意,这对于不是指针的 const 类型也是如此,因为如果 `T` 不是指针,`std::remove_pointer&lt;T&gt;` 会生成 `T`。 (2认同)