#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, конструктор по умолчанию определяется для встроенных типов как инициализация с нулевым значением.
Итак, чтобы получить такую функцию, ваш класс комплексных чисел должен поддерживать конструктор по умолчанию, то есть конструктор без аргументов.