2016-10-24 2 views
1

Я могу успешно сделать C бросок списка инициализации для массива символьных строк, но не могу заставить его работать с C++ гипса (static_cast):Кастинг списка инициализатора анонимного массива

int main() 
{ 
    char x[] = "test 123"; 

    // This works fine: 

    char **foo = (char *[]) { "a", x, "abc" }; 
    std::cout << "[0]: " << foo[0] << " [1]: " << foo[1] 
      << " [2]: " << foo[2] << std::endl; 

    // This will not compile ("expected primary-expression before '{' token"): 

    //char **bar = static_cast<char *[]>({ "a", x, "abc" }); 
    //std::cout << "[0]: " << bar[0] << " [1]: " << bar[1] 
    //   << " [2]: " << bar[2] << std::endl; 
} 

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

В конечном итоге причина, по которой я прошу об этом, заключается в том, что я вызываю функцию с указателем массива символов в качестве параметра, и я хотел бы использовать анонимный массив в качестве вызывающего аргумента.

Я использую GCC 4.4.6.

+0

Это от C99, * "Постфиксное выражение, состоящее из имени типа в скобках, за которым следует скопированный закрытый список инициализаторов, представляет собой ** составной литерал **." *, Это не скопированный инициализатор, как в C++ –

+0

Если вы хотите использовать синтаксис с принудительным инициализатором в любом случае, изменить подпись этой функции, чтобы принять 'std :: array ' –

ответ

3

Я могу успешно сделать C бросок списка инициализации для массива символьных строк

Нет, вы не можете. Вы не использовали список инициализаторов, а не листинг C. То, что вы использовали, было сложным литералом. Это C-языковая функция, которая не существует в C++. Некоторые компиляторы поддерживают их на C++ в качестве расширения языка.

Я настоятельно рекомендую вам использовать параметр компилятора, который, по крайней мере, предупреждает, когда вы используете нестандартные функции, чтобы избежать путаницы.

, но не могу заставить его работать с C++ отбрасываемой

Вы не можете бросить выражение списка инициализатор. Вам нужно будет инициализировать именованный массив обычно, а затем указатель, хотя вам вряд ли когда-либо понадобится отдельная переменная указателя, так как массив в любом случае неявно распадается на указатель в большинстве контекстов.

const char* arr[] = { "a", x, "abc" }; 
const char** foo = arr; 

почему я спрашиваю это то, что я называю функцию, которая имеет обугленный указатель массива в качестве параметра, и я хотел бы использовать анонимный массив в качестве вызывающего аргумента.

Если вы можете изменить функцию, то есть способы разрешить вызов без именованного массива. Вы можете принять std::initializer_list или тип, который может быть создан из списка инициализаторов, например, экземпляр std::array.


PS. Неявное преобразование из строкового литерала в char* также запрещено на C++, но допускается некоторыми компиляторами в качестве расширения языка. Используйте здесь const char*.

+0

Я столкнулся с этим документом https://gcc.gnu.org/onlinedocs/ GCC/Соединение-Literals.html. Я не был уверен, что это применимо, поскольку в этом случае «х» не является литералом (но, может быть, его значение копируется как литерал в составный литерал?). Кроме того, этот документ был немного неясен в отношении того, действительно ли это было броском или нет. Он ссылается на выражение в скобках как на литье, но также говорит, что результат отличается от результата.Ваш ответ (и Piotr's) дает больше ясности. Функция, о которой я упоминал, является наследием, поэтому я не могу ее изменить. – user3065699

+0

@ user3065699 Для наглядности: компоненты составного литерала не должны быть литералами. В документе, который вы указываете, показан пример с нелитеральным значением для поля. – user2079303

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

  • Нет связанных вопросов^_^