Вывод типа C ++ для статического метода фабрики - PullRequest
0 голосов
/ 24 ноября 2018

Начиная с C ++ 17, теперь намного проще создать экземпляр класса, который имеет много параметров шаблона, которые могут быть автоматически выведены из вызова конструктора.

В моем проекте у меня есть иерархия классов шаблонов, которая можетбыть вложенными друг в друга, что приводит к огромным именам типов, что является причиной, по которой вывод аргументов шаблона класса так хорош.

Однако я использую статические фабричные методы для упрощения динамического конструирования классов (в основном я просто возвращаю shared_ptrs, содержащий только что созданный объект).Как и в приведенном ниже примере

#include <iostream>
#include <memory>

template <typename T>
struct S {
    const std::shared_ptr<T> m_t;
    S(std::shared_ptr<T> t):
        m_t {std::move(t)} {}

    template<typename ...Args>
    static S create(Args&&... args);
};

template <typename T>
template <typename ...Args>
std::shared_ptr<S<T>> S<T>::create(Args&&... args) {
    return std::make_shared<S<T>>(std::forward<Args>(args)...);
}




int main() {
    auto s1 = S{std::make_shared<int>(6)};
    // auto s2 = S::create(std::make_shared<int>(5));   // DOESN'T work
}

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

1 Ответ

0 голосов
/ 24 ноября 2018
template <typename ...Args>
auto createS(Args&&... args) {
    return std::make_shared<decltype(S{std::forward<Args>(args)...})>(std::forward<Args>(args)...);
}

int main() {
    auto s1 = S{std::make_shared<int>(6)};
    auto s2 = createS(std::make_shared<int>(5));
}

Это должно гарантировать, что тип выводится точно так же, как для s1.

Фактически вы можете обобщить это, чтобы сделать любой вывод аргумента шаблона класса:

template <template<typename...> class Tmpl, typename ...Args>
auto make_shared_deduced(Args&&... args) {
    return std::make_shared<decltype(Tmpl{std::forward<Args>(args)...})>(std::forward<Args>(args)...);
}

int main() {
    auto s1 = S{std::make_shared<int>(6)};
    auto s2 = make_shared_deduced<S>(std::make_shared<int>(5));
}

См. Также стандартное предложение P1069R0 .

Хотите ли вы все эти shared_ptr Я не знаю.Вероятно, их следует использовать только в очень конкретных случаях, а не в общем случае.

...