Как преобразовать переменную в векторе, чтобы она была держателем аргументов? - PullRequest
0 голосов
/ 16 октября 2018

Я нашел это решение .Это работает, но я хочу, чтобы мой класс был владельцем аргументов.У меня есть следующий код:

template <class val_t>
class exp_t {
public:
    exp_t() {}
    virtual ~exp_t() {}

    virtual bool is(const std::vector<val_t> &kb) const = 0;
};

template <class val_t>
class fact_t: exp_t<val_t> {
public:
    const val_t m_value;

    fact_t(const val_t value): m_value{value} {}

    virtual bool is(const std::vector<val_t> &kb) const {
        return std::find(kb.begin(), kb.end(), m_value) != kb.end();
    }
};

template <class val_t>
class not_t: public exp_t<val_t> {
    exp_t<val_t> m_exp;
public:
    not_t(exp_t<val_t> exp): exp_t<val_t>(), m_exp{exp} {}

    virtual bool is(const std::vector<val_t> &kb) const override {
        return !m_exp.is(kb);
    }
};

template <class val_t, class ... args_t>
class and_t: public exp_t<val_t> {
    std::vector<exp_t<val_t>> m_exps;
public:
    and_t(args_t... exps) : exp_t<val_t>(), m_exps{{exps...}} {}

    virtual bool is(const std::vector<val_t> &kb) const override {
        for (auto &exp : m_exps) {
            if (!exp.is(kb)) { return false; }
        }

        return true;
    }
};

Мне нужно, чтобы я мог написать что-то вроде ниже:

exp_t<int> *get_exp() {  
    return new and_t<int>(fact_t<int>(5), fact_t<int>(6));
}

Т.е. чтобы я мог вернуть мой exp_t, и он сохранил переданные аргументы (например, используя семантику перемещения, я знаю, как сделать классы подвижными, но я не знаю, как переписать конструктор and_t, чтобы передать его и преобразовать в std::vector).
Как изменить класс and_t?Возможно ли это в C ++?

PS Я пытался самостоятельно читать о вариагах, но ничего не понял просто.

1 Ответ

0 голосов
/ 16 октября 2018

Т.е. я мог вернуть свой exp_t, и он сохранил переданные аргументы (например, используя семантику перемещения, я знаю, как сделать классы подвижными, но я не знаю, как переписать конструктор and_t, чтобы передать его и преобразовать вstd :: vector)

Если вы знаете (если вы уверены ), что все аргументы являются r-значениями, вы можете использовать семантику перемещения следующим образом

 and_t (args_t && ... exps)
    : exp_t<val_t>(), m_exps{{std::move(exps)...}}
  { }

В противном случае (если некоторые аргументы могут быть r-значениями, некоторые l-значениями), вы можете использовать совершенную пересылку

template <typename ... Args>
and_t (Args && ... exps)
   : exp_t<val_t>(), m_exps{{std::forward<Args>(exps)...}}
 { }

Таким образом, вы перемещаете r-значения и копируете l-значения.

Я полагаю, что лучший способ - второй (идеальная пересылка), поэтому нет необходимости в args_t вариационном списке типов для and_t класса.

...