typedef для enum
От: Аноним  
Дата: 19.08.09 10:51
Оценка:
Хочется вытащить enum из недр:
namespace X {
   namespace Y {
       class Z {
       public:
           enum MyEnum { a, b, c};
       };
   }
}


в "рабочий класс"
class MyClass
{
     typedef X::Y::Z::MyEnum MyEnum;
};


Однако при этом возникают проблемы с его использованием. В принципе моя 2005 студия понимает явное специфицирование enum:
class MyClass
{
public:
    typedef X::Y::Z::MyEnum MyEnum;
    void DoSomething() {
       // MyEnum value = a          -- так не компилируется
       MyEnum value = MyEnum::a; // -- так работает 

    } 
}


Но если пытаться использовать этот enum снаружи компилятор падает в ice:
class AnotherClass
{
    void DoAnotherThing() {
       MyClass::MyEnum anotherValue = MyClass::MyEnum::a;  // <-- тут падает
    }
}


Код привожу схематично, не уверен что в нём ошибка воспроизведётся.
Но вопрос в любом случае остаётся открытым — как правильно задать typedef для enum, желательно без нестандартных расширений языка?
Re: typedef для enum
От: Bell Россия  
Дата: 19.08.09 11:09
Оценка:
Здравствуйте, Аноним, Вы писали:

Первое, что приходит на ум — внести перечисление в скоуп MyClass с помошью наследования:

class MyClass : public X::Y::Z
{
public:
    void DoSomething() {
       // MyEnum value = a          -- так не компилируется
       MyEnum value = a; // -- так работает 

    } 
};

class AnotherClass
{
    void DoAnotherThing() {
       MyClass::MyEnum anotherValue = MyClass::a;  // Ок
    }
};
Любите книгу — источник знаний (с) М.Горький
Re[2]: typedef для enum
От: Аноним  
Дата: 19.08.09 11:34
Оценка:
Здравствуйте, Bell, Вы писали:

B>Первое, что приходит на ум — внести перечисление в скоуп MyClass с помошью наследования:

Работать будет, но идеологически неверно — "is-a" парадигма и всё такое.
Re: typedef для enum
От: kvser  
Дата: 19.08.09 12:04
Оценка:
Здравствуйте, Аноним, Вы писали:

забей ..глянь
Автор: kvser
Дата: 13.08.08
Re[2]: typedef для enum
От: Аноним  
Дата: 19.08.09 12:27
Оценка:
Здравствуйте, kvser, Вы писали:

K>забей ..глянь
Автор: kvser
Дата: 13.08.08

Видимо придётся . Самое обидное, что почти работает. Если в студии навсети мышкой на "MyClass::MyEnum::a", то во всплывающей подсказке всё правильно пишет "X:Y:Z:a = 0", а во время компиляции ice.
Re: typedef для enum
От: Sheridan Россия  
Дата: 19.08.09 12:44
Оценка: :)
Приветствую, Анонимус, вы писали:
А чем не нравится
#define a X::Y::MyEnum::a
#define b X::Y::MyEnum::b
#define c X::Y::MyEnum::c

Да и вообще насколько я понимаю — стандартный подход такой:
namespace X
{
  namespace Y
  {
    class Z
      {
        public:
        enum MyEnum 
        { 
          a, 
          #define a X::Y::MyEnum::a
          b, 
          #define b X::Y::MyEnum::b
          c
          #define c X::Y::MyEnum::c
        };
       };
    }
 }
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re: typedef для enum
От: Vain Россия google.ru
Дата: 19.08.09 13:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Хочется вытащить enum из недр:

A>...
А>Код привожу схематично, не уверен что в нём ошибка воспроизведётся.
А>Но вопрос в любом случае остаётся открытым — как правильно задать typedef для enum, желательно без нестандартных расширений языка?
namespace X {
   namespace Y {
       class Z {
       public:
           enum MyEnum { a, b, c};
       };
   }
}

typedef X::Y::Z MyEnum_class;

class MyClass
{
public:
    typedef MyEnum_class::MyEnum MyEnum;
    void DoSomething() {
        MyEnum value = MyEnum_class::a;
    }
};

class AnotherClass
{
    void DoAnotherThing() {
      MyClass::MyEnum anotherValue = MyEnum_class::a;
    }
};
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: typedef для enum
От: Programador  
Дата: 19.08.09 13:19
Оценка:
Здравствуйте, Аноним,

namespace X {
   namespace Y {
       class Z {
       public:
           enum MyEnum { a, b, c};
       };
   }
}

class MyClass
{
public:
    typedef X::Y::Z::MyEnum MyClass::MyEnum;
    void DoSomething() {
       MyEnum value2 = MyEnum::a;
    } 
};


class AnotherClass
{
    typedef MyClass::MyEnum AnotherClass::MyEnum;
    void DoAnotherThing() {
      MyClass::MyEnum anotherValue=MyEnum::a;
    }
};


так компилируется


А>Но вопрос в любом случае остаётся открытым — как правильно задать typedef для enum, желательно без нестандартных расширений языка?

а правильно ли это
Re: typedef для enum
От: blackhearted Украина  
Дата: 19.08.09 14:00
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Хочется вытащить enum из недр:

А>
А>namespace X {
А>   namespace Y {
А>       class Z {
А>       public:
А>           enum MyEnum { a, b, c};
А>       };
А>   }
А>}
А>



Я бы порекомендовал вынести enum из определения класса — воизбежание проблем со сборкой
Re[2]: typedef для enum
От: Alexey F  
Дата: 19.08.09 14:36
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>А чем не нравится

S>
S>#define a X::Y::MyEnum::a
S>#define b X::Y::MyEnum::b
S>#define c X::Y::MyEnum::c
S>

[...skip...]

И загнать a, b, c в глобальное пространство имён, да так, что нельзя будет без undef или скобок обратиться к другим переменным и перечислениям, лежащим в других namespace, но с тем же именем?
Re[3]: typedef для enum
От: Sheridan Россия  
Дата: 19.08.09 15:08
Оценка:
Приветствую, Alexey F, вы писали:

AF> И загнать a, b, c в глобальное пространство имён, да так, что нельзя будет без undef или скобок обратиться к другим переменным и перечислениям, лежащим в других namespace, но с тем же именем?


А анонимус разве не подобного хочет?
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re[4]: typedef для enum
От: Alexey F  
Дата: 19.08.09 15:56
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>А анонимус разве не подобного хочет?


Да, вроде, хочет enum в другой класс перенести:

Хочется вытащить enum из недр:
[...skip...]
в "рабочий класс"


Но даже если бы хотел вытащить в глобальное, использовать для такой цели макросы, ИМХО — нецелесообразно.
Во-первых, у них могут быть очень неудобные имена (если, конечно, константы не определяются с именами в ВЕРХНЕМ регистре ). Во-вторых, уже просто так не используешь разные константы с одним именем из разных пространств имён:
#include <iostream>
#include <ostream>

// В одном include-файле:
namespace Y {
    namespace SomethingOther {
        enum {
            firstConstant = 42,
            somethingOtherConstant = 42 * 2
        };

        namespace X {
            enum {
                firstConstant = 43
            };
        }
    }
}


// В другом include-файле, подключаемом после предыдущего:
namespace X {
    enum {
        firstConstant = 0,
        #define firstConstant X::firstConstant
        secondConstant = 1
        #define secondConstant X::secondConstant
    };
}

// ...

int main () {
    // Думаю, здесь разработчик имел ввиду значение 42, а никак не 43, т.к. конструкция ниже развернулась
    // макросом в Y::SomethingOther:: X::firstConstant.
    // Главное, подмена произошла без шума, пыли и возражений компилятора, а заметить такое среди другого кода - :xz:
    std::cout << Y::SomethingOther::firstConstant << std::endl;
}
Re: typedef для enum
От: Programador  
Дата: 19.08.09 20:07
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>     typedef X::Y::Z::MyEnum MyEnum;
А>

это работает, скорее надо писать

typedef ::X::Y::Z::MyEnum MyEnum;

хоть МС и такую глупость жрет
typedef ::X::Y::Z::MyEnum MyClass::MyEnum;




А>
А>       MyEnum value = MyEnum::a; // -- так работает 
А>


А вот это интересный момент g++ comeau ведут себя так как будто MyEnum:: инвалидная конструкция. При этом
struct Z
{  enum MyEnum { a, b, c};
   enum MyEnum2 { a, b, c};
};

дает ошибку. Если имена констант в enum разные то он всеже не дает присвоить переменной другую константу. Единственным квалификатором является Z:: без всяких Z::MyEnum:: . Конструктор по умолчанию есть Z::MyEnum() дает 0, есть и Z::MyEnum(а) но в Z:: сам имена не ищет
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.