【问题标题】:Variadic template, get function arguments value可变参数模板,获取函数参数值
【发布时间】:2014-03-01 04:40:56
【问题描述】:

我的问题如下: 我有一个这样声明的类:

template<typename ReturnType, typename... Args>
class API
{
    ReturnType operator()(Args... args)
    {
       // Get argument 0
       // Get argument 1
    }
};

我需要将参数加一,到目前为止,我想出的唯一方法(但我无法让它工作)是使用std::get,例如:

std::get<0>(args);

当然,这会导致很多错误。 我是可变参数模板(以及 C++11 的新手),所以我现在很迷茫。

我怎样才能一一得到这些论点? 任何帮助将不胜感激。

【问题讨论】:

  • 你所说的“得到...一个一个”到底是什么意思?
  • 我的意思是这样获取它们:DWORD arg0 = "args[0]"DWORD arg1 = args[1] 等我的意思是,foreach arg 传递给函数,访问它的值
  • 尝试std::tuple&lt;Args&gt;,但对于您的应用程序,我有点迷失了方向。您可能需要运行时索引,而不是静态 (0,1,2)。不知道。你比我更了解你的需求。
  • 你想用这些参数做什么?
  • 这很难解释,我要推它的值,比如foreach argument: (code)=0x68, (code+1)=value

标签: c++ c++11 variadic-templates variadic-functions


【解决方案1】:

在临时元组 (Live at Coliru) 中捕获 args:

ReturnType operator()(Args... args)
{
   static_assert(sizeof...(args) >= 3, "Uh-oh, too few args.");
   // Capture args in a tuple
   auto&& t = std::forward_as_tuple(args...);
   // Get argument 0
   std::cout << std::get<0>(t) << '\n';
   // Get argument 1
   std::cout << std::get<1>(t) << '\n';
   // Get argument 2
   std::cout << std::get<2>(t) << '\n';
}

std::forward_as_tuple 使用完美转发来捕获对args 的引用,所以应该没有复制。

【讨论】:

  • +1 表示std::forward_as_tuple,但我能问一下为什么auto&amp;&amp; 而不是普通的auto 吗?无论如何,编译器都会优化掉 move 构造,对吧?
  • @Snps 是的,很可能会忽略来自forward_as_tuple 的返回移动/复制。我对auto&amp;&amp; 的使用可能是不必要的偏执。充满右值引用的整个tuple 就像氪石,我觉得我应该用钳子处理它。
【解决方案2】:

你可以使用递归。

这是一个例子:

#include <iostream>

template<typename ReturnType>
class API {
public:
    template<typename Arg>
    ReturnType operator()(Arg&& arg) {
        // do something with arg
        return (ReturnType) arg;
    }

    template<typename Head, typename... Tail>
     ReturnType operator()(Head&& head, Tail&&... tail) {
        // do something with return values
        auto temp = operator()(std::forward<Head>(head));
        return temp + operator()(std::forward<Tail>(tail)...);
    }
};

int main() {
    API<int> api;
    auto foo = api(1, 2l, 2.0f);
    std::cout << foo;
    return 0;
}

【讨论】:

  • 我实际上发现@WhozCraig 的建议可行。只需将元组设置为std::tuple&lt;Args...&gt; targs(args...);,然后使用std::get&lt;i&gt;(targs);。无论如何,谢谢,它帮助我更好地理解可变参数函数。
猜你喜欢
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
相关资源
最近更新 更多