C++外部声明隔离
C++ External Declaration Isolation
请考虑以下事项:
namespace N {
extern "C" void f();
}
void g() {
N::f();
}
此代码声明命名空间内具有 C 链接的外部函数。这使得从私有命名空间引用此类函数成为可能,从而避免了由普通全局外部声明引起的命名空间污染。它还允许客户端代码为同一函数发出其他(希望兼容的(声明而不会发生冲突,即使在全局命名空间中也是如此,可能源自供应商提供的标头包含。
我经常依赖 C 和 C++ 中的类似构造将编译与某些库提供的编写不良或冲突的头文件隔离开来。(在 C 语言中,这是通过在函数作用域发出所需的声明来实现的,如果不是在函数作用域不允许extern
链接声明,这在C++中也是可能的。这对于正确链接到定义良好的 ABI 特别有用,而不必依赖供应商提供的头文件。
是否可以对具有常规C++链接的函数或方法执行相同的操作?也就是说:在私有命名空间(或任何类型的本地范围内(声明具有C++链接的外部函数,但该函数可能是指在另一个命名空间中实际定义的函数?
预期功能(伪代码(:
namespace N {
// Actually should link with P::f() (and not N::f()).
extern "C++" void f();
}
void g() {
N::f(); // P::f();
}
对于源文件(与头文件相反(,这显然不是问题,因为在这种情况下命名空间污染无关紧要。因此,此问题主要涉及隔离库头文件中的声明(用于模板和内联函数(。
欢迎特定于编译器的解决方案(MSVC和GCC感兴趣(。
示例:假设我的库名为 Lib1
,我想声明 Lib1
命名空间中的所有内容。
// Lib1.hpp
namespace Lib1 {
class Class1;
void func1();
// ...
}
现在假设我的库引用了另一个库,Lib2
,这是其他人提供的 C 库。
/* Lib2.h */
#ifdef __cplusplus
extern "C" {
#endif
struct Struct2;
void func2();
/* ... */
#ifdef __cplusplus
}
#endif
在我的库中,如果出于某种原因需要,我可以引用Lib2
中的实体,而不必包含Lib2.h
:
// Lib1.hpp
namespace Lib1 {
extern "C" void func2();
inline void inlineX() {
func2();
}
}
同时,客户端代码可以自由地包含Lib1.hpp
和Lib2.h
(考虑到它是C++友好的(,而不会发生冲突。
现在,假设有第三个库 Lib3
,它是一个C++库,并在 Lib3
命名空间中声明实体。
// Lib3.hpp
namespace Lib3 {
class Class3;
void func3();
// ...
}
有没有办法以与Lib2
相同的方式与Lib3
联系起来?也就是说:引用Lib1.hpp
内部Lib3
实体,不包括Lib3.hpp
但仍然允许客户端代码同时包含Lib1.hpp
和Lib3.hpp
,没有麻烦?
如果在 Lib1
中声明:
// Lib1.hpp
namespace Lib3 {
void func3();
}
namespace Lib1 {
inline void inlineY() {
Lib3::func3();
}
}
那么如果客户端代码同时包含Lib1.hpp
和Lib3.hpp
,则可能会发生冲突 - 当然不是在这个声明相同的简单示例中,但实际情况中的细微差异可能会在语法级别触发警告或错误,即使基础 ABI 相同,因为这违反了不声明 Lib1
命名空间之外的任何内容的前提。
希望这有助于理解这个问题。
这不正是 using
指令在C++中的预期用法吗?
// Lib3.hpp
#pragma once
namespace Lib3 {
void func3();
}
// Lib1.hpp
#include <Lib3.hpp>
namespace Lib1 {
using Lib3::func3;
}
- .cpp和.h文件中的模板专用化声明
- 未在作用域中声明unordered_map
- C++避免重复声明的语法是什么
- 如何确保C++函数在定义之前声明(如override关键字)
- 带内存和隔离功能的SQLite
- 错误:未在此范围内声明'reverse'
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 为什么在定义函数之前先声明它
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- #ifdef和未声明的标识符
- 没有显式声明的int[]中的foreach
- 在基于范围的for循环中使用结构化绑定声明
- 在将变量声明为引用时,堆在释放后使用
- C++:无法访问声明的受保护成员
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 尝试访问标头声明成员时出现隔离错误
- 声明/定义返回具有自动返回类型的 valarray 的函数时的隔离错误
- C++外部声明隔离