【问题标题】:How to pass variadic parameters from one template to another如何将可变参数从一个模板传递到另一个模板
【发布时间】:2020-07-13 03:23:22
【问题描述】:

我有这个代码:

#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 类按钮>(const char [8], int, int, int)'等错误”。如果我们注释“addObject”函数,它编译得很好。

如何以正确的方式将args传递给另一个模板?

【问题讨论】:

  • 这里Button 不是类型;这是一个模板。由于它本身不是一种类型,因此将其作为 typename 参数传递是没有意义的。将main 中的行更改为addObject&lt;Button&lt;int, int int.&gt;&gt;("BtnName", 0, 1, 2); 有帮助吗?显然它并不理想(因为你需要使用 template template 参数,我现在没有时间写一个完整的答案),但如果这有帮助它会给你一个地方开始。

标签: c++ templates c++17 variadic-templates


【解决方案1】:

Button 是类模板;在addObject&lt;Button&gt;("BtnName", 0, 1, 2); 中使用它时,您必须为其指定模板参数,例如Button&lt;...some arguments...&gt;

除了上面的解决方案,也许你想将模板参数Args从类移动到Button的构造函数,然后可以从函数参数(即std::forward&lt;Args&gt;(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 &lt;string&gt;

【讨论】:

  • 应该使用带有转发引用的 std::forward
【解决方案2】:

您可以制作具有模板模板类型参数的模板,这样您就不必指定 args 类型,如下所示

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多