在 C++17 / C++20 中获取参数包的最后一个元素
Get Last element of parameter pack in C++17 / C++20
我想获取参数包的最后一个元素。我用下面的代码 GodBolt:
template<typename... Args>
auto last(Args&&... args){
const auto& last = (args, ...);
return last;
}
但现在我收到警告
left operand of comma operator has no effect
但这正是我想要实现的...有没有办法说清楚。
一般来说,我喜欢收到未使用值的警告,所以我不想禁用所有这些值 (-Wno-unused-value)。
此外,我可以使用递归模板来完成,但折叠表达式在这里似乎更好。
在任何函数调用中包装 args
将删除警告。
您可以专门为此目的制作一个身份功能,但您也可以使用 std::forward
并获得适当的转发作为奖励。
template<typename... Args>
decltype(auto) last(Args&&... args){
return (std::forward<Args>(args), ...);
}
创建元组并获取最后一个元素:
template<typename... Args>
auto last(Args&&... args)
{
return std::get<sizeof...(Args)-1>(std::forward_as_tuple(args...));
}
测试:
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
您可以使用其他实现(它的效率较低,但编译器应该能够消除此处的低效率)
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)... ); }
正如 HolyBlackCat 所建议的那样,删除此警告的最简单方法是使用这样的 "identity / dummy-function":
template<typename T>
constexpr inline decltype(auto) identityFkt(T&& t)
{
return std::forward<T>(t);
}
可以这样使用:
const auto& last = (identityFkt(std::forward<AParamPack>(aParamPack)), ...);
它产生相同的程序集(已检查 @godbolt)- 没有开销(使用 -O3)。
谢谢:@HolyBlackCat
我想获取参数包的最后一个元素。我用下面的代码 GodBolt:
template<typename... Args>
auto last(Args&&... args){
const auto& last = (args, ...);
return last;
}
但现在我收到警告
left operand of comma operator has no effect
但这正是我想要实现的...有没有办法说清楚。 一般来说,我喜欢收到未使用值的警告,所以我不想禁用所有这些值 (-Wno-unused-value)。
此外,我可以使用递归模板来完成,但折叠表达式在这里似乎更好。
在任何函数调用中包装 args
将删除警告。
您可以专门为此目的制作一个身份功能,但您也可以使用 std::forward
并获得适当的转发作为奖励。
template<typename... Args>
decltype(auto) last(Args&&... args){
return (std::forward<Args>(args), ...);
}
创建元组并获取最后一个元素:
template<typename... Args>
auto last(Args&&... args)
{
return std::get<sizeof...(Args)-1>(std::forward_as_tuple(args...));
}
测试:
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您可以使用其他实现(它的效率较低,但编译器应该能够消除此处的低效率)
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)... ); }
正如 HolyBlackCat 所建议的那样,删除此警告的最简单方法是使用这样的 "identity / dummy-function":
template<typename T>
constexpr inline decltype(auto) identityFkt(T&& t)
{
return std::forward<T>(t);
}
可以这样使用:
const auto& last = (identityFkt(std::forward<AParamPack>(aParamPack)), ...);
它产生相同的程序集(已检查 @godbolt)- 没有开销(使用 -O3)。
谢谢:@HolyBlackCat