2017-02-02 3 views
2

В основном я интересно ли что-то вродеМогу ли я указать указатель на указатель на const в C++?

f(const void* a){ 
    // This is also what `(char**) a` would do behind the scenes 
    char** string_a_ptr {reinterpret_cast<char**>(const_cast<void*>(a))}; 

    // ... 

возможно при сохранении const спецификатора.

Мой вопрос возник во время упражнения о C-массивах на C++. Из-за C мне пришлось передать указатель функции с аргументами const void*. В этом случае он указывал на массив C-строк. Чтобы привести его к правильному типу, мне пришлось отбросить const. Есть ли способ в C++ получить что-то вроде указателя (const char *) * "`?

Я опробовал const char** (без const_cast), который дает

reinterpret_cast от типа 'сопзЬ пустота *' напечатать 'константный символ **' отбрасывает прочь отборочные

и (const*)*, которая дает синтаксическую ошибку

ожидаемого типа-спецификатор перед «(» лексем

Это чисто академический вопрос. Я знаю, что проблему можно решить проще и экономить, используя std::string и #include <algorithm>.

В то время как я нахожусь там, существуют ли иногда преимущества использования C-конструкций в C++ или их всегда следует избегать, если это возможно? Я только немного справился с проблемами с C-кодом на C++, но он уже вызывает немало головных болей и заставляет меня смотреть очень близко под капот, хотя в моей жизни я написал много кода C. Или вы предпочитаете использовать квалификатор extern C и писать C-код в чистом C?

+1

'const void *' будет 'char * const *'. (Это более очевидно, если вы последовательно устанавливаете классификатор 'const':' void const * '.) – Ryan

+0

Я понимаю. Переписывание этого как 'void const *' именно то, что решает мою путаницу. Благодаря! – maow

+1

«есть ли преимущества иногда использования C-конструкций в C++« Да. Но вы всегда должны стараться избегать их и знать, насколько конструкция C стоит вам в удобочитаемости, правильности текста или ремонтопригодности. В случае 'void *', это все три из них, которые вы теряете. – dascandy

ответ

4

Это будет char* const *.

Есть три места в двойном указателе положить сопзЬ:

const char** 

указателя на указатель, на персонаж вы не можете изменить.

char *const * 

Указатель, указатель, который вы не можете изменить, персонажу.

char ** const 

Указатель, который вы не можете изменить, указателю, персонажу.

Вы можете смешать их, чтобы изготовить разные детали.

2

Я считаю, что это то, что вы ищете:

const char * const * string_a_ptr = static_cast<const char * const *>(a); 

[Live example]

Можно даже бросить первый const, если вы хотите (и это имеет смысл).

Объяснение:

const void * a означает, что a указывает на то (void), который является const. Поэтому, если вы добавили a к другому указателю, он также должен указать на то, что находится const. В вашем случае вы отбрасываете указатель на char*. Следовательно, char* должен быть const. Синтаксис для создания константного указателя (не указатель на константу) должен поставить const справа от *. Следовательно, char* const *.

Смежные вопросы