Удаление неиспользуемых статических элементов создания экземпляров шаблона

В настоящее время я занимаюсь разработкой встроенного C ++ на платформе STM32. Наша команда оценивает использование шаблонов для параметризации драйверов для различных низкоуровневых аппаратных устройств.

Все допустимые специализации шаблонов известны заранее, поэтому мы можем явно указать все допустимые специализации внутри файла реализации (отдельно реализация и объявление). Фактически, для нас явная специализация весьма полезна, поскольку помогает документировать жизнеспособные наборы параметров.

// 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>;

Хотя обычно фактически будет использоваться только одна из специализаций, код, сгенерированный для неиспользуемых специализаций, удаляется компоновщиком из окончательного изображения, что мы и хотим.

Однако статические переменные-члены - period_transfer в приведенном выше примере - каждой специализации шаблона остаются в исполняемом файле, как можно увидеть на карте памяти, сгенерированной arm-none-eabi -nm инструмент. Вероятно, это связано с тем, что i2c_transfer не является POD, но имеет определяемый пользователем конструктор. Когда конструктор удаляется, превращая объект в тип POD, статические члены также исчезают.

Есть ли способ удалить статические не-POD-члены явно созданных, но неиспользуемых шаблонов?

С уважением, Арне

Правка №1: переосмыслив проблему, я пришел к следующему решению, которое, по-видимому, решает проблему.

Когда класс i2c_transfer , который на самом деле имеет свои конструкторы только для ясности и простоты использования, перемещает элементы данных в базовый класс POD i2c_transfer_pod следующим образом:

 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 также удаляются из окончательного исполняемого файла (как предлагает файл карты).

Правка №2: Хотя отвечать самому себе кажется немного неубедительным ... Я прошу комментариев по предлагаемому решению. Есть ли способ более элегантный? Действительно ли компилятор (как я полагаю) оптимизирует дополнительные производные?

Редактировать № 3: Я закрываю вопрос, так как решение работает для меня. Было бы неплохо глубже понять причину наблюдаемого поведения.

Рассматриваемый компилятор - arm-none-eabi-gcc (Sourcery G ++ Lite 2011.03-42) 4.5.2

9
задан Arne 18 January 2012 в 07:19
поделиться