2012-11-20 83 views
4

看來std :: remove_const無法刪除const char*的常量。請看下面的代碼:這個程序的如何從'char const *'中刪除const

#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*

+5

'字符常量*'是一個指向const的指針,它不是const本身。 – Pubby

+0

你發佈的代碼甚至不會在沒有'typename std :: remove_const ...'的gcc上編譯......' – Praetorian

+0

是的,我必須爲gcc編譯器添加typename。 gcc的代碼在這裏:http://ideone.com/Vd25T8 – Uri

回答

6

如果你想刪除你需要一個解決方案,遞歸去除各級常量所有常量預選賽:

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'; 
} 
+0

如果提問者需要這個好主意。 –

+0

非常漂亮...... – Uri

8

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,然後取出常量得到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