использовать класс и перечисление с тем же именем?

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

Пример:

namespace foo {
    enum bar {
        BAD
    };

    class BAD {
        void worse () {
            bar b = BAD; // error
        }
    };
};
11
задан cairol 12 February 2010 в 09:49
поделиться

4 ответа

Не уверен, подняли ли вы его или кто-то еще, но, пожалуйста, посмотрите: http://connect.microsoft.com/VisualStudio/feedback/details/530392/wmi-publishing-fails-on-permission-error-please-provide-a-way-to-override-codepath-in-system-management-instrumentation-schemanaming-in-app-config-web-config

Это может помочь вам лучше понять основную причину проблемы

-121--4028729-

mysql эквивалент верхнего и вы можете найти больше о LIMIT в MySql Doc

-121--2321892-

Это одна из тех сложных частей, как выполняется поиск имени.

В C++ есть две области идентификаторов: одна для типов классов и общая область идентификаторов. Значение перечисления BAD находится в области общего идентификатора, а тип класса BAR - в области идентификатора класса. Именно поэтому вам разрешено иметь как значение перечисления, так и класс с одинаковым именем: оба имени не сталкиваются.

В классе BAD правила поиска идентификаторов обнаружат класс BAD до того, как он найдет перечисление и, следовательно, ошибку. Теперь, если вы полностью квалифицировали идентификатор, то поиск имени сначала проверит область глобального идентификатора и сопоставит значение перечисления. На противоположном конце необходимо добавить ключевое слово struct или class для объявления переменных типа BAD.

namespace foo {
   enum bad { BAD; };
   class BAD {
      void worse() { bad b = ::foo::BAD; } // fully qualified will match the enum
   };
}
int main() {
   // foo::BAD b;    // error, foo::BAD is an enum, not a type
   class foo::BAD b; // correct
}

Теперь, я бы посоветовал против этого использования. Как правило, не рекомендуется повторно использовать такой идентификатор. Код будет более сложным и, вероятно, вводящим в заблуждение для случайного читателя (один и тот же неквалифицированный идентификатор относится к разным вещам при использовании в разных контекстах). Если имена действительно должны быть BAD , попробуйте использовать включающее пространство имен или класс для класса или перечисления (предпочтительнее перечисление).

9
ответ дан 3 December 2019 в 08:29
поделиться

Нет, это невозможно. Вы должны использовать действительный идентификатор. Действительный идентификатор означает, что вы должны иметь возможность идентифицировать с ним . :)

0
ответ дан 3 December 2019 в 08:29
поделиться

xwininfo и xprop позволяет получить то, что вы хотите, но это немного сложно.

xwininfo позволяет получить все известные окна, а xprop запросить X об идентификаторе одного окна для параметра _NET_WM_PID.

До сих пор хакерским способом было бы:

#!/bin/sh

findpid=$1

known_windows=$(xwininfo -root -children|sed -e 's/^ *//'|grep -E "^0x"|awk '{ print $1 }')

for id in ${known_windows}
do
    xp=$(xprop -id $id _NET_WM_PID)
    if test $? -eq 0; then
        pid=$(xprop -id $id _NET_WM_PID|cut -d'=' -f2|tr -d ' ')

        if test "x${pid}" = x${findpid}
        then
            echo "Windows Id: $id"
        fi
    fi
done

Результат:

mycroft:~ $ ./find_windows.sh 1919
Windows Id: 0x1800748
Windows Id: 0x181b221
Windows Id: 0x1803ad5
Windows Id: 0x181f681
Windows Id: 0x181f658
Windows Id: 0x180006d
Windows Id: 0x1800003
Windows Id: 0x1800001
Windows Id: 0x180001e

Как вы увидите, один процесс может иметь определенное количество известных окон, даже если вы видите только одно на экране.

Может быть, вы должны получить эти инструменты источники, чтобы сделать то, что вы хотите.

-121--1279054-

Для этого не нужно использовать Indy. При необходимости можно использовать TWebBrowser. IHTMLWindow2 интерфейс имеет функцию execScript. Так может быть:

var
  Doc : IHTMLDocument2;
  Win : IHTMLWindow2;
  aBrowser : TWebBrowser; 
//...
begin
  //...
  Doc := aBrowser.Document as IHTMLDocument2;
  Win := Doc.parentWindow;
  Win.execScript('alert(SomeMessage);', 'JavaScript');
end;
-121--4746271-
 bar b = foo::BAD;

или если вы находитесь в глобальном пространстве имен

 bar b = ::BAD;

, но перегрузка имени не является тем, что я рекомендую. C++ 0X позволит

 bar b = bar::BAD;

, что является лучшим решением, если приемлема зависимость от C++ 0X.

Как и было обещано, объяснение

9,1/2

Если имя класса объявлено в области, где также объявлен объект, функция или перечислитель с тем же именем, то оба объявления находятся в области действия, на класс можно ссылаться только с помощью разработанного спецификатора типа (3.4.4)

Спецификатор разработанного типа имеет вид

class BAD b;

Для совместимости с C, где имена тэгов находятся в другом пространстве имен и должны иметь [i] typedef [/i] eded, если требуется использовать их без спецификатора разработанного типа. (Хорошо известным примером с функцией является stat структуры и stat функции в Unix).

Это объясняет, почему возможна перегрузка имени для обозначения класса и перечислителя. Причина, по которой BAD обозначает класс, заключается в том, что имя класса также определяется в области класса, а в определении функции члена область поиска определяется следующим образом: - объем функции члена - объем класса - пространство имен, содержащее определение класса

BAD, найдено в области класса, поэтому поиск пространства имен foo не выполняется.

5
ответ дан 3 December 2019 в 08:29
поделиться

Это работает в VS2008, но дает предупреждение:

bar b = bar::BAD;

Это не то, что я могу порекомендовать.

Вы должны поместить перечисление в другое пространство имен внутри foo и квалифицировать как bar , так и BAD с новым пространством имен.

0
ответ дан 3 December 2019 в 08:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: