Оптимизация std::copy/memcpy/memmove

Я заглянул в GCC STL (4.6.1) и увидел, что std::copy() использует оптимизированную версию на тот случай, если встроенный __is_trivial() оценивается как true.

Поскольку шаблоны std::copy() и std::reverse_copy() очень удобны для копирования элементов в массивах, я хотел бы их использовать. Однако у меня есть некоторые типы (которые являются результатом создания экземпляров шаблона), которые представляют собой структуры, содержащие некоторые тривиальные значения, без указателей и без конструктора копирования или оператора присваивания.

Достаточно ли умен G++, чтобы понять, что мой тип на самом деле тривиален? Есть ли способ в С++ 98 убедиться, что реализация STL знает, что мой тип тривиален?

Я предполагаю, что в С++ 11 все станет удобно, используя черту типа is_trivial<>. Это правильно?

Спасибо!

РЕДАКТИРОВАТЬ: извините, что так поздно с этим, но вот пример довольно простого класса Type, который не тривиален для GCC и llvm. Любые идеи?

#include <iostream>

struct Spec;

template <typename TValue, typename TSpec>
class Type
{
public:
    TValue value;

    Type() : value(0) {}
};

int main()
{
    std::cerr << "__is_trivial(...) == "
              << __is_trivial(Type<char, Spec>) << '\n';                                                                                                                                                                                                                                    
    return 0;
} 

person Manuel    schedule 18.01.2012    source источник
comment
С++ 03 POD также запрещают конструкторы по умолчанию, насколько я помню, что, вероятно, мешает этому быть тривиальным.   -  person Mooing Duck    schedule 18.01.2012
comment
@MooingDuck: Спасибо, я думаю, это объяснение. Вместе с ответом Матье это отвечает на мой вопрос.   -  person Manuel    schedule 18.01.2012


Ответы (2)


Были некоторые споры о том, что означает trivial.

Например, ваш пример не является тривиальным, насколько я могу судить (я думаю, что std::is_trivially_default_constructible вернет false).

В вашем случае, я думаю, вам понадобится новый трейт std::is_trivially_copyable, который более мелкозернистый. Итак... обновите свой компилятор?

person Matthieu M.    schedule 18.01.2012

__is_trivial дает правильное значение для всех типов.

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

std::is_trivial в С++ 11 просто стандартизирует эту функцию, и нет никаких причин, чтобы реализация не использовала ее.

person spraff    schedule 18.01.2012
comment
По-видимому, __is_trivial не может определить, является ли тип простым копированием. :( Смотрите пример в моем обновлении. - person Manuel; 18.01.2012