私は現在、STM32プラットフォーム上のC++開発に組み込まれています。私たちのチームは、さまざまな低レベルのハードウェアデバイスのドライバをパラメータ化するテンプレートの使用を評価しています。未使用テンプレートインスタンシエーションの静的メンバーの削除
すべての有効なテンプレートの特殊化は事前にわかっていますので、実装ファイル内ですべての有効な特殊化を明示的に指定できます(実装と宣言は分離されています)。事実、明示的な特殊化は実行可能なパラメータセットを文書化するのに役立つので、非常に有用です。
// file i2c_dev.h
template<typename traits>
struct i2c_dev
{
public:
static void init();
static void send();
static bool busy();
...
private:
static i2c_transfer periodic_transfer; // class with used-defined constructor
};
// traits class for configuration A
struct i2c_dev_traitsA
{
enum
{
I2Cx_BASE = I2C1_BASE
, PORTx_BASE = GPIOB_BASE
, PORTx_PIN_TX = PB08
, PORTx_PIN_RX = PB09
};
};
// traits class for configuration B, different I2C peripherial and pinout
struct i2c_dev_traitsB
{
enum
{
I2Cx_BASE = I2C2_BASE
, PORTx_BASE = GPIOA_BASE
, PORTx_PIN_TX = PA01
, PORTx_PIN_RX = PA02
};
};
// file i2c_dev.cpp
// Implementation of template functions
template<typename traits>
void i2c_devy<traits>::init() { ... }
...
// explcitly specialize for all valid traits classes
template class i2c_dev<i2c_dev_traitsA>;
template class i2c_dev<i2c_dev_traitsB>;
専門の一般一つだけが実際に使用されていますが、未使用の専門分野のために生成されたコードは、私たちが望む正確に何であるリンカーによって、最終的なイメージから削除されます。
arm-none-eabi-nm
ツールで生成されたメモリマップに示されているように、各テンプレートのスペシャライゼーションのスタティックメンバ変数-は実行可能ファイルに残ります。これはおそらく、i2c_transfer
がPODではなく、ユーザー定義のコンストラクタを持っているためです。コンストラクタが削除され、そのことがPOD型に変わると、静的メンバーも消滅します。
明示的にインスタンス化されているが使用されていないテンプレートの静的な非PODメンバーを削除する方法はありますか?
よろしく、 アルネ
編集#1:問題を再考した後、私は明らかに問題を修正し、次の解決策、思い付きました。
実際にはそれが唯一の明快さと使いやすさのためのコンストラクタは、そのデータメンバは、POD基本クラスには、このようなi2c_transfer_pod
を移動したのですクラスi2c_transfer
があります
struct i2c_transfer_pod
{
protected:
uint16_t m_size;
char* m_buffer;
};
struct i2c_transfer : public i2c_transfer_pod
{
public:
i2c_transfer();
i2c_transfer(i2c_direction_enum dir, char*buffer, uint16_t count);
bool failed();
bool succeeded();
};
その後、未使用i2c_dev<traits>
の静的メンバを特殊化は最終的な実行可能ファイルからも削除されます(マップファイルが示唆するように)。
編集#2:one-selfに答えるのに少し不自由が感じられますが、提案された解決策についてコメントをお願いします。おそらくよりエレガントな方法はありますか?コンパイラは実際に(私が推測するように)追加の導出を最適化していますか?
編集#3:解決策が私に役立つので、私は質問を閉じます。観察された行動の理由をより深く理解することは良いことでしょう。問題の
コンパイラが(編集#1から)arm-none-eabi-gcc (Sourcery G++ Lite 2011.03-42) 4.5.2
問題の解決策を見つけた場合は、回答として投稿する必要があります。 –
奇妙なコンパイラ・ティックのような音ですが、本当に違いはありません。 – Xeo
どのような色んなコンパイラが、どのバージョンですか? –