簡體   English   中英

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

[英]how to forward-declare std::set in c++?

為了加快編譯過程,我試圖通過前向聲明MyClass.hpp容器(例如 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>& );
}

眾所周知,header <set> 非常長且復雜。 如果我們將#include <set>添加到 MyClass.hpp 中,實際上每個使用 MyClass_t 的翻譯單元都必須隱式包含 header <set>。 但我認為沒有必要,因為不是每個使用 MyClass_t 的翻譯單元都會調用MyClass_t::showSet ,所以我認為簡化是有道理的。

怎么做?

在此先感謝,請原諒我糟糕的英語。

命名空間的目的之一是分離來自不同來源的代碼。 這通常被認為是避免名稱沖突,但它更深層次。

當一個庫定義一個命名空間時,它(通常)聲稱完全擁有它。 該庫保留更改命名空間中定義的所有內容的任何和所有方面的權利,通常只保證公共 API。 這延伸到前向聲明。 除非另有說明,否則命名空間中的任何前向聲明都是庫的域,因為庫可能希望在幕后進行更改。 一些庫認真對待這一點並提供前向聲明頭,但如果沒有這些,你就不走運了。

一般來說,不要期望能夠轉發聲明您無法控制的任何內容。 即使它最初可以工作,它也有可能在庫的任何升級/補丁中中斷。


繼續std::setstd命名空間是為標准庫保留的。 標准庫允許您在受限情況下在std命名空間中聲明一些東西,但除此之外它對您來說是禁止的。 不幸的是,對於您的目標,標准庫不需要前向聲明標頭。 如果您希望您的代碼在編譯器升級后是跨平台的和/或穩定的,則需要包含完整的 header。

切線:這是指定將您自己的定義添加到namespace std是未定義行為的基礎。 並不是說這些東西一定會破壞某些東西,而是語言標准不能保證到底什么東西會破壞東西。 (實際上,如果您要在namespace std中定義一個名為supercalifragilisticiwillmisspellthis的 class ,可能什么都不會發生。)為了簡單起見,應用了“未定義行為” label 並且實現具有最大的自由度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM