Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > раскрыть ns в класс-scope


Автор: mes 8.5.2009, 12:48
столкнулся с вопросом

есть ряд типов определенных в namespace.
Код

namespace Оbject 
{
  struct SDetail1 {};
  struct SDetail2 {};
  struct SDetail3 {};
}


есть класс
Код

class CObject
{
   typedef Object::SDetail1 SDetail1;
   typedef Object::SDetail2 SDetail2;
   typedef Object::SDetail3 SDetail3;      
..
};

хотелось бы вместо тайпдефинга, просто открыть пространство имен в класс
Код

class CObject
{
   using namespace Object; // но не получается :(
};


Может у кого нибудь есть предложение по боле-менее симпатичному решению данного вопросика ?
В душе теплится (хоть и малая) надежда, что я просто синтаксиса для данного случая не знаю.
Заранее спасибо за участие в теме smile




Автор: mes 8.5.2009, 14:03
насколько я понял безымянное пространство имен должно быть видно только внутри файла в котором оно определено.
Попробовал приучить его:
Код

// a.h
namespace A
{
    namespace Object
    {
        struct S1 {};
        struct S2 {};
    }

    namespace { using namespace A::Object; }

   class CObject
    {
        S1 s1;
        S2 s2;
    };
}

проверяем
Код

//a.cpp
    A::CObject obj;
    A::S1 s1;   // S1 попало в ns А !

Кто-нибудь может разъяснить мое непонимание ситуации ?

Автор: azesmcar 8.5.2009, 14:19
mes

Цитата(стандарт)

An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a translation unit are replaced by the same identifier and this identifier
differs from all other identifiers in the entire program


Цитата(mes @  8.5.2009,  14:03 Найти цитируемый пост)
A::S1 s1;   // S1 попало в ns А !

А почему он должен был не попасть?

Добавлено через 2 минуты и 48 секунд
Цитата(mes @  8.5.2009,  12:48 Найти цитируемый пост)
Может у кого нибудь есть предложение по боле-менее симпатичному решению данного вопросика ?

над этим думаю smile

Автор: mes 8.5.2009, 14:27
Цитата(azesmcar @  8.5.2009,  13:19 Найти цитируемый пост)
А почему он должен был не попасть?

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

namespace A {
namespace  {  struct S1 {};  }
}

Код

namespace A {
  struct S1 {};  
}


П.С. что выражено в приведенной ссылке из стандарта мне тоже неясно..  smile 
Или отупел или день магнитных бурь. 

Автор: azesmcar 8.5.2009, 14:33
Цитата(mes @  8.5.2009,  14:27 Найти цитируемый пост)
вот я никак и не пойму в чем отличие безымяннного неймспейса, от неиспользования неймспейса.


Цитата(mes @  8.5.2009,  14:27 Найти цитируемый пост)
т.е в чем разница нижеприведенных кодов :


в том что
Код

namespace A {
namespace  {  struct S1 {};  }
}

ведет себя как еслиб было написано
Код

namespace A {
    namespace TEST_CPP_NAMESPACE {}

    using namespace TEST_CPP_NAMESPACE;

    namespace TEST_CPP_NAMESPACE
    {
        struct S1 {};
    }
}

а разница в том что доступ к глобальным переменным из другого translation unit -a extern-ом не получится, так как обявленные в анонимном пространстве имен глобальные переменные имеют internal linkage.

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

The use of the static keyword is deprecated when declaring objects in a namespace scope (see annex D);
the unnamed-namespace provides a superior alternative.


Добавлено через 14 минут и 14 секунд
Как вариант решения изначального вопроса..не подойдет написать свой класс в том же неймспейсе?
Код

namespace Object
{
    class CObject
    {
    };
}

Автор: Lazin 8.5.2009, 14:50
Цитата(mes @  8.5.2009,  14:03 Найти цитируемый пост)
насколько я понял безымянное пространство имен должно быть видно только внутри файла в котором оно определено.


Цитата(mes @  8.5.2009,  14:27 Найти цитируемый пост)
вот я никак и не пойму в чем отличие безымяннного неймспейса, от неиспользования неймспейса.


допустим у нас есть заголовочный файл Foo.h
Код


#pragma once

int foo;



мы его подключаем в 2х срр файлах, A и B, в результате получим ошибку во время компоновки, можно объявить переменную как статическую, а можно поместить в анонимное пространство имен

foo.h
Код

#pragma once

namespace
{
int foo;
}

Автор: mes 8.5.2009, 14:54
Цитата(azesmcar @  8.5.2009,  13:33 Найти цитируемый пост)
а разница в том что доступ к глобальным переменным из другого translation unit -a extern-ом не получится, так как обявленные в анонимном пространстве имен глобальные переменные имеют internal linkage.


Цитата(Lazin @  8.5.2009,  13:50 Найти цитируемый пост)
мы его подключаем в 2х срр файлах, A и B, в результате получим ошибку во время компоновки, можно объявить переменную как статическую, а можно поместить в анонимное пространство имен

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

Цитата(azesmcar @  8.5.2009,  13:33 Найти цитируемый пост)
Как вариант решения изначального вопроса..не подойдет написать свой класс в том же неймспейсе?

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

Добавлено @ 15:07
на текущий момент остановился на на такой форме записи :

Код

//a.h
namespace A
{
    namespace Object
    {
        struct S1 {};
        struct S2 {};
        struct S3 {};
    }

    class CObject
    {
        Object::S1 s1;  // в описании класса используем "полные пути" к "составляющим"
        Object::S2 s2;
       public:
        void f();
    };
}

Код

// a.cpp

using A::CObject;
using namespace A::Object;   // а в реализации открываем то, что нам нужно.

void CObject::f()
{
    S3 s3;
}

Автор: azesmcar 8.5.2009, 15:21
mes
 smile 
решения получше не вижу smile
и кстати не думаю что стоит искать

Автор: mes 8.5.2009, 16:05
Цитата(azesmcar @  8.5.2009,  14:21 Найти цитируемый пост)
решения получше не вижу smile
и кстати не думаю что стоит искать


Решение опробовал - эта часть рефакторинга прошла успешно.

azesmcar, 
Lazin, спасибо за участие и пояснения.  smile 

Автор: J0ker 8.5.2009, 17:04
Цитата(azesmcar @  8.5.2009,  15:21 Найти цитируемый пост)
решения получше не вижу 

ИМХО изначальный вариант с typedef куда логичней и безопасней

Автор: azesmcar 8.5.2009, 17:07
Цитата(J0ker @  8.5.2009,  17:04 Найти цитируемый пост)
ИМХО изначальный вариант с typedef куда логичней и безопасней 

открывать неймспейс в cpp файле вполне нормально. Что здесь конкретно понижает безопасность?
Мне кажется это больше дело вкуса, чем безопасности.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)