Значение инициализация автоматического объекта?
Я пишу класс шаблона и в какой-то момент своего кода хотел бы иметь возможность инициализировать значение объекта параметризованного типа в стеке. Прямо сейчас я выполняю это, написав что-то по этому поводу:
template <typename T> void MyClass<T>::doSomething() {
T valueInitialized = T();
/* ... */
}
Этот код работает, но (если компилятор не является интеллектуальным) он требует ненужного создания и уничтожения временного объекта T
. То, что я хотел бы написать, следующее: я знаю неверно:
template <typename T> void MyClass<T>::doSomething() {
T valueInitialized(); // WRONG: This is a prototype!
/* ... */
}
Мой вопрос заключается в том, есть ли хороший способ инициализировать объект автоматически, без необходимости явно создавать временный объект и назначать его автоматическому объекту. Это можно сделать? Или T var = T();
так хорошо, как это получается?
Ответы
Ответ 1
В следующей версии используется копирование-инициализация, которая "вероятно прекрасна" 95% времени в С++ 03:
T var = T();
Но для общего кода С++ 03 вы всегда должны отдавать предпочтение прямой инициализации для учета других 5%:
T var((T())); // extra parentheses avoid the most vexing parse – the extra parentheses
// force the contents to be evaluated as an expression, thus implicitly
// *not* as a declaration.
Или еще лучше, используйте Boost. Утилита .ValueInit, которая создает идеальное поведение для вас наряду с обходными решениями для различных недостатков компилятора (к сожалению, больше, чем можно было бы подумать):
boost::value_initialized<T> var;
Для С++ 11 можно использовать синтаксис инициализации списка для достижения прямой инициализации значения в значительно менее шумном/уродливом виде:
T var{}; // unambiguously value-initialization*
(* Nb это только инициализация значений для типов, у которых нет унарного конструктора, берущего некоторый std::initializer_list<>
; для типов, которые делают, этот конструктор будет называться вместо этого - "равномерная инициализация" действительно... Конечно, чистый результат должен быть одинаковым для нормальных типов.)
Ответ 2
Вы можете использовать фигурные скобки в С++ 0x:
T valueInitialized{};
Ответ 3
Нет, нет другого способа надежно инициализировать тип шаблона в С++ 03.
Если вы можете рассчитывать на T
только типы классов со стандартными конструкторами, вы можете просто написать
T valueInitialized;
но если T
может быть встроенным,
T valueInitialized = T();
- это путь.
У вас есть причина не доверять своему компилятору, чтобы оптимизировать эту копию?