Вопрос:
Как я могу удалить все определители констант из типа данных?
Я попытался использовать std::remove_cv но он не работал.
std::remove_cv< const char *>::type
Разве это не так, как std::remove_cv<char*>::type?
Благодарю.
Лучший ответ:
Эта черта делает все правильно:
const char* – это то же самое, что и char const* и ни одно из них не совпадает с char* const. Таким образом, в вашем случае его pointee thats const, а не указатель. И remove_const (несколько логически) удаляет только внешнюю const, а не внутренние.
Если вы действительно хотите удалить const Несс в pointee, вы можете сделать это следующим образом:
using T = char const*; using NoConstT = std::add_pointer<std::remove_cv<std::remove_pointer<T>::type>::type>::type;
(Хотя std::add_pointer<T>::type можно отбросить в пользу более простого T*…)
То есть: удалить указатель, удалить const из pointee, сделать результат указатель снова.
Фактически, это хорошая возможность использовать библиотеку превосходных колес R. Martinho Fernandes, которая обеспечивает удобные ярлыки для таких вложенных черт:
#include <wheels/meta.h++> using namespace wheels; … using NoConstT = AddPointer<RemoveCv<RemovePointer<T>>>;
Гораздо удобнее читать.
Ответ №1
Нет стандартного способа сделать это, вам нужно будет написать свой собственный:
template<typename T> struct remove_const_recursive { typedef T type; }; template<typename T> struct remove_const_recursive<T const volatile> { typedef typename remove_const_recursive<T>::type volatile type; }; template<typename T> struct remove_const_recursive<T volatile> { typedef typename remove_const_recursive<T>::type volatile type; }; template<typename T> struct remove_const_recursive<T const> { typedef typename remove_const_recursive<T>::type type; }; template<typename T> struct remove_const_recursive<T&> { typedef typename remove_const_recursive<T>::type& type; }; template<typename T> struct remove_const_recursive<T*> { typedef typename remove_const_recursive<T>::type* type; }; Ответ №2
Сделайте это рекурсивно. Сопоставьте T* по специализации, затем повторно примените * и т.д.
Ответ №3
Вы можете увидеть различия между константным указателем и указателем, указывающим на const и различные type_traits с
#include <iostream> #include <type_traits> int main() { std::cout << std::is_same<std::remove_const<const char*>::type, char*>::value << ‘n’; std::cout << std::is_same<std::remove_const<char* const>::type, char*>::value << ‘n’; std::cout << std::is_same<std::add_pointer<std::remove_const<std::remove_pointer<const char*>::type>::type>::type, char*>::value << ‘n’; return 0; }
который дает в качестве вывода
0
1
1