【问题标题】:standard c++11 way to remove all pointers of a type标准c ++ 11删除类型的所有指针的方法
【发布时间】:2012-03-24 12:07:31
【问题描述】:

有没有办法用一些 c++11 或最多一个 boost 库来做到这一点?

#include <iostream>
#include <typeinfo>
using namespace std;

template <typename T> class remove_all_pointers{
public:
    typedef T type;
};

template <typename T> class remove_all_pointers<T*>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

int main(){
    //correctly prints 'i' on gcc
    cout<<typeid(remove_all_pointers<int****>::type).name()<<endl;
}

【问题讨论】:

  • 你想从什么中删除这些指针?
  • 您的remove_all_pointers 模板确实删除了所有指针。你还需要什么?
  • 这里的问题是“标准库中是否有与我编写的代码相同的工作”?
  • @downvoters 我看不出寻找标准功能来实现某些目标的问题。即使您可以自己编写 3 行代码,为什么不看看是否有用于此目的的标准工具呢? OP 需要它来做什么与回答问题几乎无关。
  • 另外,这并不是一个如此深奥的功能,以至于人们想知道为什么有人可能想要它。 C++11 标准和 Boost 已经有了remove_pointer。他所要求的只是remove_all_pointer,就像它具有用于删除所有数组限定符的remove_all_extent。他想要基本类型;为什么想要这么有问题的东西?

标签: c++ boost c++11 typetraits


【解决方案1】:

这并不适用于所有指针类型。您还需要考虑不同的 cv 限定符:

template <typename T> class remove_all_pointers<T* const>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* volatile>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* const volatile >{
public:
    typedef typename remove_all_pointers<T>::type type;
};

【讨论】:

  • 好点。您可以使用 std:remove_cv 并调度到执行海报所具有的例程。
【解决方案2】:

从 C++17 开始,您可以创建一个可读、简单且可识别 cv 限定符的元函数。

像这样使用它:

int main()
{
    remove_all_pointers_t<int* const* volatile* const volatile*> v = 42;
    return 0;
}

C++20

#include <type_traits>

template<typename T>
struct remove_all_pointers : std::conditional_t<
    std::is_pointer_v<T>,
    remove_all_pointers<
        std::remove_pointer_t<T>
    >,
    std::type_identity<T>
>
{};

template<typename T>
using remove_all_pointers_t = typename remove_all_pointers<T>::type;

C++17

在 C++17 中,std::type_identity 尚不可用,std::identity 不再可用,因此您需要创建自己的“身份”元函数:

#include <type_traits>

// your custom 'identity' meta function
template <typename T>
struct identity
{
    using type = T;
};

template<typename T>
struct remove_all_pointers : std::conditional_t<
    std::is_pointer_v<T>,
    remove_all_pointers<
        std::remove_pointer_t<T>
    >,
    identity<T>
>
{};

template<typename T>
using remove_all_pointers_t = typename remove_all_pointers<T>::type;

【讨论】:

    【解决方案3】:

    Boost 和 C++11 都没有这样的特征模板。但是您的代码应该可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-14
      • 2021-06-14
      • 2017-11-13
      • 2023-04-07
      • 2014-08-03
      • 2010-09-08
      • 1970-01-01
      • 2019-09-24
      相关资源
      最近更新 更多