C++Cast или преобразовать указатель (T *) на два-сопзе (T сопзЬ * сопзИте) указатель
Я хочу знать, если указатель, который уже не является двух- const
указателя (например, T const * const
) могут быть неявно или явно лишены, обработаны через что-либо (например, функция) или иным образом преобразованы, чтобы получить T const * const
, без или до использования для инициализации переменной, объявленной как T const * const
. Как я могу это сделать?
Я подумал, что если бы я начал с T*
, то один const_cast
(или два, в случае, если бросок может бросить только в одном const
в то время) было бы достаточно, но, видимо, это не так. Многие переменные в коде показывают другую неудачную попытку получения T const * const
посредством кастинга или возврата из функции. Каждый кастинг не смог вернуть указатель с завершающим const
. (Я имею в виду const
слева от *
в качестве ведущего const
и один справа от *
в качестве конечного const
.) Из-за неудачных бросков я безуспешно пытался принудительно выполнить const
с помощью прямой инициализации. Это было составлено в VC11
. g++ on 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()
исключает конечный const?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
единственное, что они могут сделать?
Спасибо за ответ; что разъясняет многие проблемы, но есть ли у вас ответ на # 10? Кроме того, вы имеете в виду, что ведущий 'const' не является модификатором' const' верхнего уровня; только конечная 'const'? Поскольку 'auto' игнорирует модификаторы констант верхнего уровня, как я могу наблюдать, желательно сохранить, немедленные результаты каждого приведения до того, как будет потерян модификатор const-уровня? Может 'const_cast (& t_type)' придать 'T *' непосредственно в 'T const * const', или мне нужны два приведения, по одному для каждого' const'? –
CodeBricks
** 5.2.8/5 ** Квалификаторы верхнего уровня выражения glvalue или * type-id *, которые являются операндом 'typeid', всегда игнорируются. –
Константа, которая применяется к объявляемой переменной, является модификатором 'const' верхнего уровня, независимо от того, лексически ли она появляется в начале или в конце. В 'const int n = 42' и' int const n = 42', модификаторы 'const' являются верхними уровнями. В 'const int * const! p', 'int const * const! p', 'typedef const int * CP; сопз! CP p', я отмечал квалификаторы верхнего уровня с восклицательным знаком. –