Как передать параметры variadi c из одного шаблона в другой - PullRequest
2 голосов
/ 01 апреля 2020

У меня есть этот код:

#include <tuple>
#include <memory>

template <typename ...Args>
class Button
{
    Button(const std::string& name, Args&& ...args) {
        std::tuple<Args...> tuple_ = std::tuple<Args...>(args...);
    }
};

template<typename T1, typename ...Args>
void addObject(const std::string& name, Args&& ...args) {
    std::unique_ptr<T1> obj(new T1(name, std::forward<Args>(args)...));
    //...rest of the code...
}

int main() {
    //if we comment the next line it compiles well
    addObject<Button>("BtnName", 0, 1, 2);
    return 0;
}

Тем не менее, он не компилируется с ошибками типа «ошибка LNK2019: неразрешенный внешний символ ...» или «нет соответствующей функции для вызова» addObject class Button> (const char [8], int, int, int) '". Если мы прокомментируем функцию «addObject», она хорошо скомпилируется.

Как правильно передать аргументы в другой шаблон?

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Button - шаблон класса; при использовании его в addObject<Button>("BtnName", 0, 1, 2); вы должны указать для него аргументы шаблона, например Button<...some arguments...>.

Помимо решения, приведенного выше, возможно, вы захотите переместить параметр шаблона Args из класса в конструктор Button, то это может быть выведено из аргументов функции (т.е. std::forward<Args>(args)...).

class Button
{
public:
    template <typename ...Args>
    Button(const std::string& name, Args&& ...args) {
        std::tuple<Args...> tuple_ = std::tuple<Args...>(std::forward<Args>(args)...);
    }
};

LIVE


Другие вопросы:

  • Конструктор Button равен private.
  • Нет #include <string>.
1 голос
/ 01 апреля 2020

Вы можете создать шаблон с параметром типа шаблона шаблона, поэтому вам не нужно указывать типы аргументов, как показано ниже

#include <tuple>
#include <memory>
#include <string>
template <typename ...Args>
struct Button
{
    Button(const std::string& name, Args&& ...args) {
        auto tuple_ = std::make_tuple<Args...>(std::forward<Args>(args)...);
    }
};

template<template <typename ...Args> typename T1, typename ...Args>
void addObject(const std::string& name, Args&& ...args) {
    auto obj = std::make_unique< T1 <Args...> >(name, std::forward<Args>(args)...);
    //...rest of the code...
}

int main() {
    addObject<Button>("BtnName", 0, 1, 2);
    return 0;
}
...