C ++
Я хочу знать, если указатель не являетсяconst
указатель (например, T const * const
) может быть явным или неявным образом приведен, обработан с помощью чего-либо (например, функции) или иным образом преобразован для получения T const * const
, без использования или перед использованием для инициализации переменной, объявленной как T const * const
, Как я могу это сделать?
Я думал, что если бы я начал с T*
тогда один const_cast
(или два, в случае, если актерский состав может быть использован только в одном const
за один раз) будет достаточно, но, видимо, это не так. Многие переменные в коде показывают другую неудачную попытку получить T const * const
через приведение или возвращение из функции. Каждый актер не смог вернуть указатель с трейлингом const
, (Я имею в виду const
слева от *
как ведущий const
и тот, что справа от *
как трейлинг const
.) Из-за неудачных бросков я безуспешно пытался заставить const
через прямую инициализацию. Это было скомпилировано в VC11
, g ++ на stack-crooked.com дает логически эквивалентный вывод консоли, хотя и с разными именами для typeid(/*...*/).name()
,
#include <iostream>
#include <typeinfo>
using namespace std;
int const * const foo()
{
return nullptr;
}
int main()
{
int x = 7;
auto a1 = &x;
cout << typeid(a1).name() << endl;
auto a2 = const_cast<int const *>(&x);
cout << typeid(a2).name() << endl;
auto a3 = const_cast<int * const>(&x);
cout << typeid(a3).name() << endl;
auto a4 = const_cast<int const * const>(&x);
cout << typeid(a4).name() << endl;
auto a5 = const_cast<int const * const>(a4);
cout << typeid(a5).name() << endl;
auto a6 = (int const * const) &x;
cout << typeid(a6).name() << endl;
auto a7 = static_cast<int const * const>(a4);
cout << typeid(a7).name() << endl;
auto a8 = reinterpret_cast<int const * const>(a4);
cout << typeid(a8).name() << endl;
auto a9 = foo();
cout << typeid(a9).name() << endl;
int const * const a10 = &x;
cout << typeid(a10).name() << endl;
cout << ( typeid(a10) == typeid(a4) ) << endl;
auto a12 = a10;
cout << typeid(a12).name() << endl;
cout << ( typeid(a12) == typeid(a4) ) << endl;
}
Ожидаемые результаты против фактических результатов и вопросы:
Номера вопросов соответствуют одинаковым номерам a#
переменные.
int *
int const *
int* const
, но получил int*
, Сделал const_cast
игнорировать его отставание const
аргумент а почему? Поскольку возвращаемое значение совпадает с константой и типом аргумента, выполнялось ли приведение вообще?int const * const
, но получил int const*
, Сделал const_cast
игнорировать его отставание const
аргумент а почему?const_cast<int const * const>
будет включать трейлинг const
в результате, учитывая, что аргумент a4
уже ведущий const
, ожидаемый int const * const
, Получил int const*
, Сделал const_cast
игнорировать его отставание const
аргумент а почему?int const * const
, Получил int const*
, Почему явное приведение все еще исключает трейлинг const
?int const * const
, Получил int const*
, Почему бы static_cast
исключить трейлинг const
?int const * const
, Получил int const*
, Почему бы reinterpret_cast
исключить трейлинг const
?int const * const
, Получил int const*
, Зачем нужна инициализация int const * const
возврат функции все еще исключает завершающий const
в результате?int const * const
, Получил int const*
из вывода консоли, но не из отладчика. a10
явно объявлен как int const * const
так почему же typeid().name()
исключить конечный констант? operator==
доходность 1
так почему же typeid()
сам (не только имя) для a10
эквивалентно тому из a4
? Списки отладчика VC11 a10
Тип как int const * const
, Почему он отличается от typeid()
а также typeid().name()
? Который правильный?a11
опущен, потому что это выглядит как слово «все».a12
быть int const * const
потому что он инициализирован a10
, который был явно объявлен int const * const
, operator==
доходность 1
, так typeid()
все еще int const*
, Получил int const*
как из консоли вывода, так и отладчика. Почему они отличаются от ожидаемого результата?Все ли приведения, возвраты функций и инициализации ограничены только приведением в одном const
вовремя? Является ведущим const
единственное, что они могут бросить?
const_cast
работает так, как вы думаете. Тем не мение, auto
не делает то, что вы думаете, что делает. auto
работает аналогично выводу параметров шаблона функции (на самом деле это определяется в терминах последнего). Теперь рассмотрим:
template<typename T>
void f(T x);
f(42);
int const n = 42;
f(n);
Оба звонка f<int>()
не f<const int>()
, Константные модификаторы верхнего уровня игнорируются выводом параметра шаблона. По той же причине в этом примере
auto a = 42; a = 84;
auto b = n; b = 84;
переменные a
а также b
имеют тип int
не const int
и может быть изменено.
Других решений пока нет …