如何在c++中使用namespace::function选择函数的单个重载
How to select a single overload of a function with using namespace::function in C++?
考虑以下c++代码:
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);
}
演示。
编辑:更好的方法是将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); }
除了剩下的答案,我还会再举一些例子。
许多c++编程书籍通常通过在源文件开头添加以下行来公开整个STD名称空间:
using namespace std;
在现实生活中,暴露完整的名称空间实际上是一种不好的做法,因为在某些时候可能会发生各种冲突,特别是当代码由从事同一任务的许多开发人员提供时。这种编程风格也违背了面向对象编程的基本规则之一——通过封装数据,避免暴露超出实际需要的内容。这就是为什么类有public和private成员,getter和setter等等。名称空间只是对信息进行分组的另一种方式。暴露整个std命名空间是违反此规则的,特别是如果您只想使用std::cout、std::cin和std::endl。您可以使用轻松地将应用于特定的函数,这允许您进行更精确的控制,并更有可能避免在某些时候可能使用的多个名称空间中的命名冲突:
using std::cout;
using std::cin;
using std::endl;
这允许您在代码中调用cout、cin和endl而不使用名称空间前缀。如果您在某些时候遇到命名冲突,使用-指令查看一组要容易得多,而不是想知道您暴露的错误来自整个命名空间的哪个地方。
如果有一个命名空间链或者命名空间的名字太长,人们也会对单个函数/变量使用using指令。如果你有
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
声明。
c++没有机制可以从命名空间中导入一个特定的函数重载。
作为一种变通方法,你可以将一个函数调用包装成一个局部函数:
static inline void f(int i) { A::f(i); }
关键字static
非常重要-
- 降低当前编译单元的全局命名空间污染的风险
- 可以在多个编译单元中执行此操作(因此可以放在头文件中)
- 它允许编译器省略额外的函数调用(调用
f()
和A::f()
在生成的代码中没有区别) - 如果从未调用
f
,则不会生成额外的代码
相关文章:
- "error: no matching function for call to"构造函数错误
- 如何使用默认参数等选择模板专业化
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++选择排序算法中的逻辑错误
- QTreeView幻灯片多选后无法使用单击选择
- 无法获取菜单选择以运行函数.C++
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 库函数需要一个 std::function<void(void)>,如何传入类函数?
- Confusion: decltype vs std::function
- 在C++中,如何通过几种类型从元组中选择多个元素
- 为什么 std::function 可以作为 std::not2 的参数?
- 'max'匹配'std::function<const int &(const int &, const int &)>'无过载
- 讨论 - 创建矩阵时的数组与向量的向量 - 什么是最实用的选择
- 传递给std::function template的template参数究竟代表什么
- 对可变参数使用声明.如何选择正确的功能
- 将带有unique_ptr的可变 lambda 传递给 const&std::function
- 使用 std::function 时选择自动返回类型而不是构造函数的调用运算符
- 如何在c++中使用namespace::function选择函数的单个重载