Инициализируйте std :: tuple с помощью аргументов variadi c в конструкторе - PullRequest
1 голос
/ 03 февраля 2020

У меня есть класс, который создает std::function. Для простоты я скажу, что std::function возвращает логическое значение для этого примера. std::function должен принимать кортеж variadi c. В настоящее время у меня есть

template<class... FuncArgs>
class Function
{
public:
    // Type that std::function returns
    using func_ret_ty = bool;

private:
    std::function<func_ret_ty(std::tuple<FuncArgs...>)> m_Function;
    std::tuple<FuncArgs...> m_Args;  // Stores m_Function's arguments

public:
    Function(
        std::function<func_ret_ty(std::tuple<FuncArgs...>)> function,
        FuncArgs... args)
        : m_Function(function)
        , m_Args(std::make_tuple(std::forward<FuncArgs>(args)...))
    {}
};

Мой вопрос прост: будет ли это работать?

В частности, я обеспокоен тем, что при объявлении типа для * 1009 существует циклическая зависимость *. У меня была еще одна мысль о реализации:

template<class FuncTy, class FuncArgs...>
class Function
{
public:
    using func_ret_ty = bool;

private:
    FuncTy m_Function;
    std::tuple<FuncArgs...> m_Args;

public:
    Function(
        FuncTy function,
        FuncArgs... args)
        : m_Args(std::make_tuple(std::forward<FuncArgs>(args)...))
    {
        static_assert(
            std::is_same_v<FuncTy, std::function<func_ret_ty(std::tuple<FuncArgs...>)>>,
            "FuncTy invalid type!"
        );

        m_Function = std::move(function);
    }
};

Вторая реализация лучше? Есть ли лучший способ go сделать это?

1 Ответ

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

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

Обратите внимание, что std::function также может принимать пакеты параметров в качестве параметров шаблона, поэтому вы также можете сделать это:

std::function<func_ret_ty(FuncArgs...)> m_Function;
...