C / Шаблон / Явная инициализация типа шаблона?

#c #templates

#c #шаблоны

Вопрос:

Предположим, что следующий фиктивный шаблон:

 template < class DataType > class Dummy
{
public:
    void init( )
    {
        m_data = DataType( 0 );
    }

private:
    DataType m_data;
};
  

Вызов init инициализирует внутренние данные. Это работает нормально, когда тип данных является стандартным типом данных (например, int или float). Когда тип данных является классом, у этого класса должен быть соответствующий конструктор.

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

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

Я думаю, например, что STL должен реализовывать подобные мысли, но я теряюсь в этом коде.

Комментарии:

1. Это зависит от того, есть ли у вас компилятор, поддерживающий C 11?

Ответ №1:

В вашем примере, я думаю, вы имели в виду:

 DataType( 0 );
  

Нет:

 Data ( 0 );
  

В любом случае попробуйте:

 m_data = DataType();
  

Это вызовет конструктор по умолчанию для типа класса или приведет к инициализации с нулевым значением для встроенного типа.

Комментарии:

1. 1: Тогда вам нужно будет потребовать, чтобы любой класс, передаваемый в качестве параметра, был сконструируемым по умолчанию, что является разумным требованием (стандарт делает это в нескольких местах, например std::map , s value-type).

2. Учитывая форму init mem-функции, кажется, что конструкция по умолчанию является требованием дизайна класса.

3. Отлично ! Я не знал, что встроенные типы инициализируются до нуля таким образом. Поэтому я буду использовать конструктор по умолчанию.

4. Если у вас C 0x, вы можете использовать идеальную пересылку в init с любыми параметрами

Ответ №2:

Вы могли бы использовать аргумент по умолчанию как:

 template <class T> 
class A
{
public:
    void init(T c = T()) //default argument
    {
        m_data = c;
    }
private:
    T m_data;
};
  

Если тип аргумента шаблона T является определяемым пользователем типом, и он не определяет конструктор по умолчанию, тогда вам нужно передать один аргумент, чтобы init() функционировать самостоятельно, иначе вы получите ошибку компиляции.

Это подход, принятый стандартной библиотекой. Например std::vector::resize() , принимает необязательный аргумент, следуя тому же обоснованию, что и упомянутое выше.

Ответ №3:

Фактически, вы думаете здесь в терминах «конструируемых по умолчанию» классов, то есть классов, которые могут быть инициализированы фактически без ввода, зависящего от класса. STL написан с учетом этого термина, и, как писал @DanielEarwicker, конструктор по умолчанию определяется для встроенных типов как инициализация с нулевым значением.

Итак, чтобы получить такую функцию, ваш класс комплексных чисел должен поддерживать конструктор по умолчанию, то есть конструктор без аргументов.