如何在c++中向前声明std::set?

问题描述 投票:1回答:1

为了加快编译过程,我试图简化我的头文件。MyClass.hpp 通过正向声明STL容器,如std::vector、std::set......。

但是 std::set 可以 可在以下代码中预先声明,而 std::vector 可以是。

namespace std {
    template<typename T, typename A> class vector;
    template<typename T, typename C, typename A> class set;
};

class MyClass_t {
        void showVector( std::vector<int>& );
        void showSet( std::set<int>& );
}

我们知道,头<set>是非常长且复杂的。如果我们添加 #include <set> 到MyClass.hpp中,事实上,每个使用MyClass_t的翻译单元都必须隐式地包含头<set>。但我认为这没有必要,因为不是每个使用MyClass_t的翻译单元都会调用 MyClass_t::showSet,所以我认为简化是有意义的。

怎么做呢?

先谢谢你,请原谅我的英语不好。

c++ set std forward-declaration
1个回答
0
投票

命名空间的目的之一是分离来自不同来源的代码。这通常被认为是为了避免名称冲突,但它涉及到更深层次的问题。

当一个库定义了一个命名空间时,它(通常)声称完全拥有它。该库保留改变命名空间中定义的一切事物的任何和所有方面的权利,通常只保证公共API。这延伸到了前向声明。命名空间中的任何前向声明都是库的领域,除非另有说明,因为库可能想在幕后改变一些东西。有些库会认真对待这一点,并提供前向声明头,但如果没有这些,你就会很幸运。

一般来说,不要指望能够向前声明任何你不控制的东西。即使一开始能正常工作,也有可能在库的任何升级补丁中被破坏。


接着说说 std::setజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ std 命名空间是为标准库保留的。标准库允许你在标准库的 std 命名空间,但在其他情况下,它对你来说是禁区。不幸的是,对于你的目标来说,标准库不需要前向声明头。如果你希望你的代码是跨平台的,或者在编译器升级后是稳定的,你将需要包含完整的头文件。

说句题外话:这就是规定在你的代码中加入自己的定义到 namespace std 是未定义的行为。并不是说这种东西一定会破坏什么东西,而是语言标准无法保证到底什么东西会破坏什么东西。(现实中,如果你要定义一个名为 supercalifragilisticiwillmisspellthisnamespace std,可能什么都不会炸掉)。) 为了简单起见,采用 "未定义行为 "的标签,并给予实现最大的自由度。

© www.soinside.com 2019 - 2024. All rights reserved.