Предположим, у меня есть метод, определенный в двух разных пространствах имен:
namespace foo
{
void print()
{
//do work...
}
}
namespace bar
{
void print()
{
//do work...
}
}
foo::print()
и bar::print()
функции абсолютно равны. Мой проект использует многочисленные вызовы этих функций.
Есть ли способ удалить один из print()
определения без изменения вызовов этих функций? Я имею в виду что-то вроде следующего (конечно, язык C ++ не позволяет эту конструкцию, это просто пример):
namespace foo, bar //wrong code!
{
void print()
{
//do work...
}
}
Если нет способа реорганизовать код так, как я хочу, скажите, пожалуйста, вам нравится следующее решение? Будете ли вы рады, если ваш проект содержит такой код? 🙂
namespace foo
{
void print()
{
//do work...
}
}
namespace bar
{
void print()
{
foo::print();
}
}
ДОБАВЛЯТЬ:
Спасибо, ребята, я полностью удовлетворен вашими ответами. Только один момент, я хочу, чтобы вы уточнить: есть ли разница между using ::foo::print
а также using foo::print
?
Вы можете достичь этого с using
декларация.
namespace foo
{
void print()
{
//do work...
}
}
namespace bar
{
using foo::print;
}
РЕДАКТИРОВАТЬ
Что касается разницы между ::foo::print
а также foo::print
: добавление завершенного имени с помощью :: означает, что вы явно ссылаетесь на имя в глобальном пространстве имен. Это можно использовать для выбора глобального, даже если есть другой элемент с таким же именем, более близкий по объему.
Как насчет using
объявление:
namespace foo
{
void print()
{
// do work ...
}
}
namespace bar
{
using ::foo::print;
}
С помощью ::foo::print
вместо foo::print
это важный момент. Если бы у вас был другой foo
Внутри bar
:
namespace foo
{
void print()
{
// 1 ...
}
}
namespace bar
{
namespace foo
{
void print()
{
// 2 ...
}
}
using foo::print; // refers to 2
using ::foo::print; // refers to 1
}
тогда вы увидите преимущество использования ::
, Подводя итог, готовимся ::
это безопасный способ гарантировать, что другое вложенное пространство имен foo
, который может быть добавлен в будущем, не принесет вам никаких сюрпризов.
С using
объявление:
namespace bar
{
using ::foo::print;
}
Наверное, лучшее решение это:
namespace foo
{
void print()
{
//do work...
}
}
namespace bar
{
void print()
{
foo::print();
}
}
Однако вы можете написать:
namespace foo
{
void print()
{
//do work...
}
}
namespace bar
{
void print()
{
//do work...
}
}
Это не рекомендуется, но зла нет. Компиляторы достаточно умны, чтобы понять, что эти две функции одинаковы и могут использовать один и тот же код сборки.
Помните, namespace
Ключевое слово предназначено для программистов, компилятор не заботится о них, потому что пространства имен компилятора подобны префиксу для функций / методов / классов.
Образец
namespace Q {
namespace V {
void f(); // enclosing namespaces are the global namespace, Q, and Q::V
class C { void m(); };
}
void V::f() { // enclosing namespaces are the global namespace, Q, and Q::V
extern void h(); // ... so this declares Q::V::h
}
void V::C::m() { // enclosing namespaces are the global namespace, Q, and Q::V
}
}