2016-02-02 2 views
0

В настоящее время (с C++ 11) просто спроектировать boost::recursive_wrapper с помощью std::unique_ptr:повышение :: recursive_wrapper и станд :: unique_ptr

template< typename T > 
class recursive_wrapper 
{ 

    std::unique_ptr<T> storage; 

public : 

    template< typename ...Args > 
    recursive_wrapper(Args &&... args) 
     : storage(std::make_unique<T>(std::forward<Args>(args)...)) 
    { ; } 

    template< typename R > 
    operator R &() noexcept 
    { 
     return static_cast< R & >(*storage); 
    } 

    template< typename R > 
    operator R const &() const noexcept 
    { 
     return static_cast< R const & >(*storage); 
    } 

    void 
    swap(recursive_wrapper & other) noexcept 
    { 
     storage.swap(other.storage); 
    } 

}; 

Но в настоящее время он разработан с помощью оператора ::new и boost::checked_delete. Сплошной практикой является использование необработанных операторов new и delete в современном C++.

Если цель только C++ 11 и новее, есть ли минусы для реализации recursive_wrapper с использованием std::unique_ptr, как это выше (я имею в виду как время компиляции производительности и времени выполнения снижения производительности, например или, может быть что-то еще)? Что делать, если обратная совместимость как требование перестала существовать?

ответ

1

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

boost::recursive_wrapper был специально разработан для обеспечения того, чтобы они содержали себя. Я уверен, что если вы проверить выполнение boost::variant вы обнаружите, что расширение шаблона рекурсивного шаблона зависит от специализации, которые выглядят примерно так:

template<class...T> 
struct SomeClass<boost::recursive_wrapper<boost::variant<T...>>> 
{ 
    .... 

, которые, если вы не планируете повторно реализовать boost::variant, чтобы использовать другой класс-оболочку, сделали бы их несовместимыми.

+0

Я не планирую использовать пользовательскую реализацию 'recursive_wrapper' для именно' boost :: variant', но для [другой реализации варианта] (https://github.com/mapbox/variant). Нет такой проблемы для этой реализации. Есть ли другие недостатки, которые только можно вообразить? – Orient

+0

@Orient нет, я так не думаю. Вы должны будете помнить, чтобы настраивать конструктор копии и оператор копирования *, если * T поддерживает эти операции. –

+0

'T' является неполным, если я использую его для определения рекурсивных структур, поэтому черты типа не являются корректными для' recursive_wrapper < T > 'в точке его создания. [Обходной путь] (https://github.com/tomilov/variant/blob/master/include/versatile/recursive_wrapper.hpp#L31), я знаю это, и я его использую. – Orient