【问题标题】:How to remove the const from 'char const*'如何从 'char const*' 中删除 const
【发布时间】:2012-11-20 18:10:13
【问题描述】:

看来std::remove_const 无法移除const char* 的常量。考虑以下代码:

#include <iostream>
#include <type_traits>
#include <typeinfo>

template< typename T >
struct S
{
    static void foo( ) {
        std::cout << typeid(T).name() << std::endl;
        std::cout << typeid( std::remove_const<T>::type ).name() << std::endl;
    }
};


int main( )
{
    S<char const*>::foo();
}

此程序的输出(在 Visual Studio 2010 上):

char const *
char const *

在 gcc 中我们有可读的输出(代码 here):

PKc
PKc

我希望在 Microsoft 编译器的第二行获得 char *,以及在 gcc 上获得任何内容(但不同于第一行)。我究竟做错了什么?如何将char const* 转为char*

【问题讨论】:

  • char const* 是指向 const 的指针,它本身不是 const。
  • 如果没有typename std::remove_const ...,您发布的代码甚至无法在 gcc 上编译
  • 是的,我必须为 gcc 编译器添加 typename。 gcc 的代码在这里:ideone.com/Vd25T8
  • @Uri 您应该始终拥有typename,而不仅仅是为 gcc 添加它。 std::remove_const&lt;T&gt;::type 是一个依赖类型(因为它依赖于 T),标准要求它前面有 typename 关键字来表明这一点。 MSVC 将在有和没有typename 的情况下编译代码,但如果你省略它,它真的不应该接受代码。 Here's 解释为什么这在 MSVC 中被破坏。

标签: c++ c++11


【解决方案1】:

char const* 是指向const char 的指针,但指针本身不是const。要从所指向的类型中删除常量,您可以这样做:

std::add_pointer<typename std::remove_const<typename std::remove_pointer<T>::type>::type>::type

或者:

typename std::remove_const<typename std::remove_pointer<T>::type>::type*

我们从const char*中删除指针得到const char,然后删除const得到char,然后将指针加回去得到char*。不是特别漂亮。测试:

typedef const char * type_before;
std::cout << typeid(type_before).name() << std::endl;
typedef typename std::remove_const<typename std::remove_pointer<type_before>::type>::type* type_after;
std::cout << typeid(type_after).name() << std::endl;

在我的系统上使用 g++,输出如下:

PKc
Pc

这应该给你一个关于“PKc”意味着什么的提示。 P 代表指针,c 代表char,K 代表konst ;)

【讨论】:

    【解决方案2】:

    如果你想删除所有 const 限定符,你需要一个从所有级别递归删除 const 的解决方案:

    template<typename T> struct remove_all_const : std::remove_const<T> {};
    
    template<typename T> struct remove_all_const<T*> {
        typedef typename remove_all_const<T>::type *type;
    };
    
    template<typename T> struct remove_all_const<T * const> {
        typedef typename remove_all_const<T>::type *type;
    };
    
    int main() {
        std::cout << typeid(remove_all_const<int const * * const>::type).name() << '\n';
    }
    

    【讨论】:

    • 好主意,如果提问者想要这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    相关资源
    最近更新 更多