简体   繁体   English

获取 C++17 / C++20 中参数包的最后一个元素

[英]Get Last element of parameter pack in C++17 / C++20

I would like to get the last element of a parameter pack.我想获取参数包的最后一个元素。 I did it with the following code GodBolt :我用下面的代码GodBolt 做到了:

template<typename... Args>
auto last(Args&&... args){
   const auto& last = (args, ...);
   return last;
}

But now I get the warning但现在我收到警告

left operand of comma operator has no effect逗号运算符的左操作数无效

But this is exactly what I wanted to achieve... Is there a way to make it clear.但这正是我想要实现的......有没有办法说清楚。 In general I like to get warnings for unused values so I don't want to disable all of them (-Wno-unused-value).一般来说,我喜欢收到未使用值的警告,所以我不想禁用所有这些值(-Wno-unused-value)。

In addition I could do it with a recursive template, but a fold expression seems to be better here.另外我可以用递归模板来做,但折叠表达式在这里似乎更好。

Wrapping args in any function call would remove the warning.在任何 function 调用中包装args将删除警告。

You could make an identity function specifically for this purpose, but you might as well use std::forward and get proper forwarding as a bonus.您可以专门为此目的创建一个身份 function ,但您不妨使用std::forward并获得适当的转发作为奖励。

template<typename... Args>
decltype(auto) last(Args&&... args){
   return (std::forward<Args>(args), ...);
}

Make a tuple and get the last element:创建一个元组并获取最后一个元素:

template<typename... Args>
auto last(Args&&... args)
{
    return std::get<sizeof...(Args)-1>(std::forward_as_tuple(args...));
}

Test:测试:

int main()
{
    auto&& last_element = last(1, 1.0, true);
    static_assert(std::is_same_v<bool, std::remove_cvref_t<decltype(last_element)>>);
}

Demo演示

C++11 Friendly Demo C++11 友好演示

As suggested by HolyBlackCat the easiest way to remove this warning is to use an "identity / dummy-function" like this:正如 HolyBlackCat 所建议的,删除此警告的最简单方法是使用这样的“身份/虚拟函数”:

template<typename T>
constexpr inline decltype(auto) identityFkt(T&& t)
{
    return std::forward<T>(t);
}

It can be used this way:可以这样使用:

const auto& last = (identityFkt(std::forward<AParamPack>(aParamPack)), ...);

It results in the same assembly (checked @ godbolt) - no overhead (with -O3).它导致相同的程序集(检查@godbolt) - 没有开销(使用-O3)。

Thank you: @HolyBlackCat谢谢:@HolyBlackCat

You can use another implementation (it's less efficient, but compiler should be able remove inefficiency here)您可以使用另一种实现(效率较低,但编译器应该能够消除此处的低效率)

template <class T>
decltype(auto) last(T && ... t) { return t; }

template <class ... TT,class T>
decltype(auto) last(T &&,TT && ... tt) { return last( std::forward<TT>(tt)... ); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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