Конфликт имен в C ++: как получить доступ к члену структуры с именем "class" - PullRequest
16 голосов
/ 08 июля 2011

Я столкнулся с проблемой именования при работе с библиотекой xlib:

Я использую структуру, в которой есть член с именем "class". Я предполагаю, что эта библиотека в основном используется в простых программах на Си. Так что проблем нет.

Но я программирую на C ++, и здесь имя «класс» является ключевым словом и не может использоваться для обозначения переменных. Итак, если я получаю доступ к структуре через

myvariable = mystruct->class;

Я получаю ошибку:

expected unqualified-id before ‘class’

Учитывая, что я не могу изменить саму структуру, как я могу получить доступ к этому члену структуры, несмотря на конфликт имен?

Ответы [ 6 ]

17 голосов
/ 08 июля 2011

Учитывая, что я не могу изменить саму структуру, как я могу получить доступ к этому члену структуры, несмотря на конфликт имен?

Может быть, вы можете переименовать его, используя #define, что-то вроде

#define class xclass
#include "header.h"
#undef class

// ...

myvariable = mystruct->xclass;
14 голосов
/ 08 июля 2011

class - это ключевое слово в C ++. Вы не можете использовать его как переменную.

Если вы хотите получить к нему доступ, вы можете написать эту часть в C, а затем скомпилировать ее с помощью компилятора c:

typedef struct foo {
    bar class;
} foo;

bar *getClassPtr(foo *p) { return &(p->class); }

Включите эту часть в код C ++, используя

extern "C" {
   bar *getClassPtr(foo *);
}
bar &getClass(foo &s) { return *getClassPtr(&s); }

Возможно, вам также понадобятся постоянные версии.

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

Возможно, вы захотите найти информацию о extern "C" .

7 голосов
/ 08 июля 2011

Вы говорите, что используете XLib.Я могу найти только два места в моем Xlib.h, где class используется в качестве члена структуры: Visual и XWindowAttributes.В обоих случаях нарушающий член обернут следующим образом:

#if defined(__cplusplus) || defined(c_plusplus)
    int c_class;
#else
    int class;
#endif

Аналогичная хакерская атака появляется в XColormapEvent, чтобы позаботиться о new элементе.

Так что с вами все будет в порядкеваш компилятор C ++ не определяет ни одного из необходимых макросов;но это также сломало бы обычные оболочки extern "C" { ... }, так что проблема, скорее всего, в другом месте.Если вы используете структуру, которая не является частью стандартного XLib, то вам следует применить вышеуказанный хак вручную и провести суровое обсуждение с автором библиотеки (а если это вы, то немного поговорите с самим собой, и мыя сделаю вид, что не слушаю).

Если у вас возникли проблемы со структурами XLib, попробуйте использовать версию имен членов C ++:

myvariable = mystruct->c_class;
mynew      = ev->c_new;
1 голос
/ 08 июля 2011

В VC ++ вы можете использовать ключевое слово расширения Microsoft: __ идентификатор

int __identifier(float);
__identifier(float) = 10.4f;

MSDN говорит, что это применимо только к / clr (Managed C ++), но это не так. Он существовал даже в VC6

1 голос
/ 08 июля 2011

Класс является зарезервированным ключевым словом в C ++ и не может использоваться в качестве имени переменной. Вам придется переименовать переменную.

0 голосов
/ 08 июля 2011

Поскольку class является ключевым словом в C ++, компилятор будет жаловаться, если вы его используете

Может быть, вы могли бы создать структуру-оболочку (в C), которая позволяет получить доступ к вашей неисправной структуре, что-то вроде

typedef struct Wrapper_ {
    faultyStruct * mystruct ;
    faultyStructClass * cls ;
} Wrapper ;

Wrapper wrap(faultyStruct * s) {
    Wrapper w = {s, &(s->class) } ;
}

Скомпилируйте этот файл с вашим компилятором C и используйте его в своем коде C ++ через extern "C"

Вы также можете использовать препроцессор для переопределения class (но я не уверен, насколько законно #define C ++ ключевые слова

...