Generi c способ построения интеллектуальных точечных типов данных, а также нормальных типов данных - PullRequest
0 голосов
/ 03 февраля 2020

Я хотел бы написать обобщенный c способ построения типа T с учетом случая, когда T - это умный указатель данных, которые я на самом деле хочу построить. Что-то вроде:

template < typename T, typename... Args >
auto
create( Args... args )
{
    return T{args...};
}

template < typename std::unique_ptr< typename T >, typename... Args >
auto
create( Args... args )
{
    return std::make_unique< T >( args... );
}

template < typename std::shared_ptr< typename T >, typename... Args >
auto
create( Args... args )
{
    return std::make_shared< T >( args... );
}

Таким образом, он, конечно, не будет компилироваться. Это просто, чтобы объяснить грубую идею. Мне нужны еще две специфические c перегрузки, которые по-прежнему являются обобщенными c, достаточными для выполнения этой работы.

Код вызывающей стороны должен быть в состоянии сделать что-то вроде этого:

const SomeType x1 = create<SomeType>(1, 2, 3);
const std::unique_ptr<SomeType> x2 = create<std::unique_ptr<SomeType>>(1, 2, 3);

1 Ответ

1 голос
/ 03 февраля 2020

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

template <typename T> struct Tag{};

template <typename T, typename... Args>
auto create_impl(Tag<T>, Args&&... args)
{
    return T{std::forward<Args>(args)...};
}

template < typename T, typename... Args >
auto create_impl(Tag<std::unique_ptr<T>>, Args&&... args)
{
    return std::make_unique<T>(std::forward<Args>(args)...);
}
template < typename T, typename... Args >
auto create_impl(Tag<std::shared_ptr<T>>, Args&&... args)
{
    return std::make_shared<T>(std::forward<Args>(args)...);
}

template <typename T, typename... Args>
auto create(Args&&... args)
{
    return create_impl(Tag<T>{}, std::forward<Args>(args)...);
}
...