Подтвердить что ты не робот

Значение инициализация автоматического объекта?

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

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(); так хорошо, как это получается?

4b9b3361

Ответ 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();

- это путь.

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