рассмотрим следующий код на С++.
namespace A {
void f() { // first function
}
void f(int) { // second function
}
}
...
using A::f; // introduces both functions
Есть ли способ ввести только одну функцию?
рассмотрим следующий код на С++.
namespace A {
void f() { // first function
}
void f(int) { // second function
}
}
...
using A::f; // introduces both functions
Есть ли способ ввести только одну функцию?
Это поведение четко определено в стандарте.
C++03 7.3.3 The using declaration
:
"... Если имя является именем перегруженной функции-члена, то все имена функций должны быть доступны.".
using
ключевое слово приведет все имена в текущую область. Так что с этим текущим кодом это невозможно.
Однако вы можете ввести имена частично в файл следующим образом:
namespace A {
void f(); // declaration
}
using A::f;
// now only `A::f()` is visible in the subsequent code
// technically `A::f(int)` is not yet visible (thus unusable)
// introduce the other function later on
namespace A {
void f(int);
}
Демо.
Edit:
Способ лучше состоит в том, чтобы поместить A::f(int)
внутри вложенного namesapce
и ввести псевдоним (для удобства использования).
namespace A {
void f();
namespace Internal {
void f(int);
}
}
using A::f;
namespace A_ = A::Internal;
Теперь другая функция также может использоваться как A_::f(int)
.
Не знаю, насколько я знаю. Вы можете написать функцию обертки, если это проблема.
void f(int i) { A::f(i); }
Я приведу еще несколько примеров в дополнение к остальным ответам.
Многие книги для программирования на С++ часто выставляют все пространство имен STD, добавляя следующую строку где-то в начале исходного файла:
using namespace std;
Появление полного пространства имен фактически является плохой практикой в реальной жизни из-за различных конфликтов, которые могут возникнуть в какой-то момент, особенно когда код предоставляется многими разработчиками, которые работают над одной и той же задачей. Такой стиль программирования также противоречит одному из основных правил объектно-ориентированного программирования - избегайте подвергать себя большему, чем это действительно необходимо, путем инкапсуляции ваших данных. Вот почему классы, например, имеют публичные и частные члены, геттеры и сеттеры и так далее. Пространства имен - это еще один способ группировки информации. Выявление всего пространства имен std противоречит этому правилу, особенно если вы хотите использовать let say только std:: cout, std:: cin и станд:: епсИ. Вы можете легко применить с помощью к определенным функциям, что позволит вам более точно контролировать и повысить вероятность избежать конфликтов имен в нескольких пространствах имен, которые вы могли бы использовать в какой-то момент:
using std::cout;
using std::cin;
using std::endl;
Это позволяет вам вызывать cout, cin и endl в коде без префикса пространства имен. Если в какой-то момент у вас возник конфликт с именами, гораздо проще посмотреть на набор с помощью -directives, а не на то, чтобы узнать, где во всем пространстве имен, которое вы обнаружили, возникает ошибка.
Люди также используют директиву с использованием для одной функции/переменной, если существует цепочка пространств имен или имя пространства имен слишком велико. Если у вас есть что-то вроде
namespace my_really_long_and_pointless_namespace_that_does_nothing_at_all {
void foo() { ... }
}
или
namespace1 {
namespace2 {
...
namepaceN {
void foo() { ... }
}
}
}
боль в прикладе должна писать всю вещь каждый раз, когда вы хотите вызвать метод foo(). Пишем
using my_really_long_and_pointless_namespace_that_does_nothing_at_all::foo;
и соответственно
using namespace1::namespace2:: ... ::namespaceN::foo;
вы пощадите свои пальцы какой-то работой.
Попробуйте сделать это:
namespace A {
void f() { // first function
} }
using A::f; // introduces only above function
namespace A {
void f(int) { // second function
}
}
Можно обернуть их в другую область:
namespace B { // Wrap the first function
void f() { A::f(); }
}
namespace C { // Wrap the second function
void f(int i) { A::f(i); }
}
int main(int argc, char *argv[])
{
{
using B::f; // Make the first function available
f();
} // Make the first function unavailable
{
using C::f; // Make the second function available
f(0);
} // Make the second function unavailable
return 0;
}
Но я не думаю, что вы можете сделать это с помощью одного объявления using
.
С++ не имеет механизма для импорта одной конкретной функции перегрузки из пространства имен.
В качестве обходного пути вы можете обернуть вызов функции в локальную функцию:
static inline void f(int i) { A::f(i); }
Ключевое слово static
очень важно -
f()
и A::f()
)f
никогда не вызывается, дополнительный код не будет создан