いくつかのヘッダーを、使用後にインクルード チェーンから除外したいと考えています。私が知っていることから、c ++ 11には除外「header.h」はありません。
疑似コード 希望的観測:
#include "the_bad_header.h" //long includechain with later unused declarations
class bulky { ... };
constexpr std::size_t bulkysize = sizeof(bulky);
forget everything included and class bulky and remember only bulkysize
問題が明らかになる私の例は次のとおりです。これは深刻な問題ではないと主張しないでください。この例は、最小限の抽象言語の使用を示すために分割されています。昔ながらの解決策とその欠点についても説明します。
古いスタイルのソリューション
justanotherheader.h:
class bulkywrap
{
public:
bulkywrap();
protected:
friend class bulkywrap_pImpl;
bulkywrap_pImpl *const pImpl; //opaque pointer, private implementation
};
justanothercppunit.cpp:
#include "justanotherheader.h"
#include "boost/lotsofheaders.hpp"
//#include more and more headers of highly complex libraries so adding millions of known types and other identifiers, macros, and so on
class bulkywrap_pImpl
{
//lots of members of types used from the other libraries
};
bulkywrap::bulkywrap()
: pImpl( new bulkywrap_pImpl() )
{}
私の現在の解決策
justanotherheader.h:
#include "stdint.h" // this is the only header I like to use, but also unnecessary.
#define UNKNOWNSIZE 12345
class bulkywrap
{
public:
bulkywrap();
protected:
friend class bulkywrap_pImpl;
bulkywrap_pImpl *const pImpl; //opaque pointer, private implementation
uint8_t pImpl_Placement[UNKNOWNSIZE]; //placement new for pImpl
};
justanothercppunit.cpp:
#include "justanotherheader.h"
#include "boost/lotsofheaders.hpp"
//#include more and more headers of highly complex libraries so adding millions of known types and other identifiers, macros, and so on
class bulkywrap_pImpl
{
//lots of members of types used from the other libraries
};
bulkywrap::bulkywrap()
: pImpl( new(this->pImpl_Placement) bulkywrap_pImpl() ) //using this here is safe
{}
したがって、上記のコードは機能しています。利点は次のとおりです。複雑さを隠し、実行時に動的なメモリの間接参照がありません。は?つまり、配置 new により、オブジェクト全体をスタックに配置でき、すべてのメンバーアドレスがコンパイル時に認識されます。私の試みは、不透明なポインターのインターフェイス設計を使用しながら、最高のパフォーマンスを実現することです。
「このパフォーマンス上の利点は、考える努力に値しない」と考える場合。その質問を残してください。
私の期待される解決策
justanotherheader.h:
#include "stdint.h" // this is the only header I like to use, but also unnecessary.
constexpr std::size_t get_bulkywrap_pImpl_Size( void ); //constexpr function forward declaration
extern constexpr std::size_t bulkywrap_pImpl_Size; //constexpr literal forward declaration with external initialization
class bulkywrap
{
public:
bulkywrap();
protected:
friend class bulkywrap_pImpl;
bulkywrap_pImpl *const pImpl; //opaque pointer, private implementation
uint8_t pImpl_Placement[get_bulkywrap_pImpl_Size()]; //undefined constexpr used
uint8_t pImpl_Placement[bulkywrap_pImpl_Size]; //alternative to above. undefined constexpr used
};
justanothercppunit.cpp:
#include "justanotherheader.h"
#include "boost/lotsofheaders.hpp"
//#include more and more headers of highly complex libraries so adding millions of known types and other identifiers, macros, and so on
class bulkywrap_pImpl
{
//lots of members of types used from the other libraries
};
constexpr std::size_t get_bulkywrap_pImpl_Size( void )
{
return sizeof(bulkywrap_pImpl);
}
constexpr std::size_t bulkywrap_pImpl_Size = sizeof(bulkywrap_pImpl);
bulkywrap::bulkywrap()
: pImpl( new(this->pImpl_Placement) bulkywrap_pImpl() ) //using this here is safe
{}
私の現在のソリューションでは、sizeof(bulkywrap_pImpl) を確認し、UNKNOWNSIZE を手動で調整する必要があります。現在、編集ユニットから他のユニットに情報を取得することはできないと思います。これは通常、正当な理由で意図されていることを知っていますが、これにより c++11 の可能性が制限されます。
私は指摘したい:
情報天気と、標準でこれが許可されていない理由を見つけるのを手伝ってください。
しかしさらに、コンパイル時にリテラル定数をコンパイルユニットから別のコンパイルユニットにエクスポートする方法の解決策を見つけたいと思います。これは単なるリテラルであるため、すべてのステートメントと式は影響を受けません。したがって、コンパイルは配列のサイズがどこから来るかに依存しません。
私の提案は、ISO-jtc1-sc22-wg21 とコンパイラの開発者にいくらかの作業をもたらしますが、すべての定義が同じ変換単位に表示される必要があるため、テンプレートと constexpr の間に関連する違いは見られません。これにより、モジュラー プログラミングとクリーンなインターフェイスが偽物になります。
いいえ: プリプロセッサ マクロ、動的な新しいメンバー関数または仮想メンバー関数を使用したくありません。クラスのサイズは const であるため、最大の const-correctness が重要です。
助けてください