Функции шаблона: конструкция по умолчанию без копирования в C ++ - PullRequest
6 голосов
/ 14 марта 2011

Учитывая

struct C { 
   C()            { printf("C::C()\n"          ); }
   C(int)         { printf("C::C(int)\n"       ); }
   C( const C& )  { printf("copy-constructed\n"); }
};

И шаблон функции

template< typename T > void foo(){
    // default-construct a temporary variable of type T
    // this is what the question is about.
    T t1;       // will be uninitialized for e.g. int, float, ...
    T t2 = T(); // will call default constructor, then copy constructor... :(
    T t3();     // deception: this is a local function declaration :(
}

int main(){
    foo<int>();
    foo<C  >();
}

Глядя на t1, он не будет инициализирован, когда, например, T. int. С другой стороны, t2 будет созданным с учетом копирования из временного создания по умолчанию.

Вопрос: возможно ли в C ++ конструировать переменную по умолчанию, отличную от template-fu?

Ответы [ 4 ]

5 голосов
/ 14 марта 2011

Вот прием, который вы можете использовать, используя локальный класс:

template <typename T> void foo() {
    struct THolder {
        T obj;
        THolder() : obj() { } // value-initialize obj
    };

    THolder t1; // t1.obj is value-initialized
}

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

Кроме того, вы можете использовать шаблон класса boost::value_initialized<T>, который в основном делает то же самое, с большей гибкостью и согласованностью, а также с обходными путями для глючных компиляторов.

В C ++ 0x, это намного проще: вы можете использовать пустой список инициализаторов:

T obj{}; // obj is value-initialized

(Насколько мне известно, только gcc 4.5+ поддерживает списки инициализаторов C ++ 0x. Clang и Visual C ++ пока нетподдержать их.)

2 голосов
/ 14 марта 2011

Если вас не волнует тот факт, что конструктор копирования должен существовать, и вы просто хотите, чтобы он не вызывался:

Не волнуйся: не будет. В этом случае вызов конструктора копирования будет . Всегда и надежно - даже при компиляции с отключенными оптимизациями (-O0).

0 голосов
/ 14 марта 2011

T t2 = T (); // вызовем конструктор по умолчанию, затем скопируем конструктор ...: (

Не на моем компиляторе (VC2008). Выход для меня это ...

C::C()
C::C()

Что я и ожидал. Я что-то упустил?

0 голосов
/ 14 марта 2011

Какой у тебя настоящий вопрос? Конструктор по умолчанию вызывается для t1 instance.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...