简体   繁体   中英

How to pass variadic parameters from one template to another

I have this code:

#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;
}

However, it is not compiling with errors like "error LNK2019: unresolved external symbol..." or "no matching function for call to 'addObject class Button>(const char [8], int, int, int)'". If we comment "addObject" function it compiles well.

How to pass args to another template in the right way?

Button is a class template; when using it in addObject<Button>("BtnName", 0, 1, 2); , you have to specify template arguments for it like Button<...some arguments...> .

Besides the solution above, maybe you want to move template parameter Args from class to the constructor of Button , then it could be deduced from the function arguments (ie 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


Other issues:

  • The constructor of Button is private .
  • There's no #include <string> .

You can make a template having a template template type parameter so you don't have to specify your args types, as follows

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM