В С++ можно ли переименовать/псевдоним имени, не относящегося к пространству имен, не относящемуся к классу?

у меня есть

namespace src {
   struct src_bar;
   void src_baz();
   template<class T> class src_qux;
}

который я хотел бы сослаться как

namespace dst {
    struct dst_bar;
    void dst_baz();
    template<class T> class dst_qux;
}

это означает, что я хотел бы «переименовать» или «псевдоним» или «переименовать» имена из src.

Для dst_bar можно, конечно, использовать namespace dst { typedef src_bar dst_bar; }. Есть ли какой-то эквивалент (не макрос), позволяющий мне переименовать src::src_baz в dst::dst_baz и src::src_qux в dst::dst_qux?

Если я не ошибаюсь, ни оператор using, ни псевдоним пространства имен не могут выполнить два других действия. Написание шаблонных функций пересылки для dst_baz() возможно, но требует знания арности src_baz. В определениях типов шаблонов dst_qux<T>::type может быть src_qux<T>, но косвенность добавляет многословия.

FWIW, мой вариант использования берет имена C, такие как somepackage_someportion_somefuncA, и предоставляет версию somepackage::someportion::somefuncA, удобную для пространства имен, чтобы другие люди могли использовать using somepackage::someportion для краткости.


person Rhys Ulerich    schedule 01.02.2012    source источник
comment
Подходит ли вам #define вариант?   -  person iammilind    schedule 01.02.2012


Ответы (3)


Для функций вам придется вручную пересылать запросы. Для типов, не являющихся шаблонами, вы можете просто указать typedef. Для типов шаблонов вы можете использовать новую функцию using в С++ 11, чтобы создать псевдоним в стиле typedef для шаблона, если ваш компилятор поддерживает его, иначе вам в основном не повезло.

person David Rodríguez - dribeas    schedule 01.02.2012
comment
Это то, что я ожидал. Спасибо, что подтвердили это. - person Rhys Ulerich; 04.02.2012

Нет, вы не можете «переименовать» что-то, чтобы оно больше не использовало свое первоначальное имя.

Однако вы можете добиться того же эффекта с помощью хитрости.

Во-первых, импортируйте заголовок для определений, которые вы хотите поместить внутри блока пространства имен:

namespace foo {
    #include "src_stuff.h"
}

Теперь у вас есть foo::src::src_bar и друзья.

Затем широко используйте typedef:

namespace bar {
    typedef foo::src::src_bar dst_bar;
}

Вуаля, у вас есть bar::dst_bar, такой же, каким был бы src::src_bar. Если вы не заботитесь о том, чтобы определения оставались доступными под старыми именами, пропустите первый шаг и просто сделайте typedefs для удобства. В конце концов, для этого они и нужны.

person Borealid    schedule 01.02.2012
comment
Включение включенного файла в пространство имен обязательно будет проблематичным... Файл реализации для этого заголовка не будет иметь пространства имен и, таким образом, будет определять функции, отличные от тех, которые объявлены в включенном таким образом заголовке. И это не решает основную часть вопроса: как сделать аналог typedefs для функций и шаблонов. - person David Rodríguez - dribeas; 01.02.2012
comment
@DavidRodríguez-dribeas Шаблоны на самом деле не мешают подходу typedef. Вы даже можете использовать макросы препроцессора, если они становятся слишком длинными. - person Borealid; 01.02.2012

Если использование макросов является для вас приемлемым вариантом, то вот одно из решений:

// declare this macro in some common file
#define CREATE(SCOPE) \
namespace SCOPE { \
   struct SCOPE## _bar; \
   void SCOPE## _baz(); \
   template<class T> class SCOPE## _qux; \
}

Использование:

CREATE(src);
CREATE(dst);
person iammilind    schedule 01.02.2012
comment
Спасибо за решение на основе макросов. - person Rhys Ulerich; 04.02.2012