【问题标题】:How to get element from parameter pack?如何从参数包中获取元素?
【发布时间】:2021-05-25 22:45:20
【问题描述】:
#include <iostream>
#include <tuple>
#include <utility>

template <typename... T>
decltype(auto) getParameterPackVals(T&&... Args) noexcept {
    return std::get<1>(std::forward_as_tuple(std::forward<T>(Args)...));
}

int main() {
    std::cout << getParameterPackVals(2, 1.0, 2.0, 3.0, 4.0, 5.0) << std::endl;
    //print(1.0, "Hello", "This", "is", "An", "Honour");
    return 0;
}

这是我当前有效的代码,使用1 作为变量的占位符。虽然当我用变量替换1 时(我在getParameterPackVals 的参数中尝试了size_tint)它不起作用。

template <size_t V, typename... T>
decltype(auto) getParameterPackVals(V n, T&&... Args){
    return std::get<n>(std::forward_as_tuple(std::forward<T>(Args)...));
}

这是我对std::get 函数工作原理的理解上的差距吗?有没有办法让它按原样工作,还是我需要编写一个全新的函数?

【问题讨论】:

  • std::get 需要一个在编译时已知的索引。函数参数永远不会是 constexpr,并且不能用于需要常量表达式的地方。

标签: c++ parameter-pack


【解决方案1】:

哇,这是我第一次自己解决!

所以在头脑风暴时,我记得如果我命名了一个模板参数,例如 size_t V,我可以在调用参数时将其传递给 &lt;V&gt;。所以我从函数参数中取出V n,并将函数称为getParameterPackVals&lt;2&gt;(1.0, 2.0, 3.0, 4.0, 5.0)。现在的最终代码是:

#include <iostream>
#include <tuple>
#include <utility>

template <size_t V, typename... T>
decltype(auto) getParameterPackVals(T&&... Args) noexcept{
    return std::get<V>(std::forward_as_tuple(std::forward<T>(Args)...));
}


int main() {
    std::cout << getParameterPackVals<2>(1.0, 2.0, 3.0, 4.0, 5.0) << std::endl;
    return 0;
}

我会留下这个问题,以防其他人遇到类似问题。

【讨论】:

  • 请注意,您的函数返回double&amp;&amp;,而不是double。获得悬空参考的风险很高。
  • 是的,我在测试时注意到,幸运的是,这只是一个小练习,可以帮助我更好地理解参数包和转发功能。您有什么建议可以避免出现悬空引用的可能性吗?
  • 我不在我的电脑上进行测试,但会删除 && 并允许左值和右值成为有效的解决方案。因为我并不真正关心只接受右值,所以 && 再次有点只是练习我一直在学习的东西,我不认为 && 的省略会导致转发问题?除非我错了
  • 我认为你的代码是正确的,你已经正确地实现了完美转发。并不比内置的? :更危险。
  • 您可以将decltype(auto) 替换为std::tuple_element_t&lt;V, std::tuple&lt;T...&gt;&gt;。如果想法是做一个完美的转发功能,而你故意想返回T&amp;&amp;而不是T,那么这个改变是不需要的,@HolyBlackCat 是对的。
猜你喜欢
  • 2019-12-17
  • 1970-01-01
  • 2017-02-27
  • 2012-06-17
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
相关资源
最近更新 更多