如何正确、优雅地实现结构化绑定的apply函数?

问题描述 投票:0回答:1
在 std 命名空间中,有一个方便的

std::apply

 函数,允许您对元组的每个元素执行操作。使用结构化绑定,我们可以为非元组类型实现相同的行为。假设我们考虑一种只有一个非静态数据成员的类型。因此,我编写了以下代码:
#include <iostream> #include <functional> #include <utility> #include <type_traits> template<class F, class T> decltype(auto) apply1(F&& func, T&& val){ if constexpr(std::is_lvalue_reference<decltype(val)>{}){ auto& [m1] = val; std::invoke(std::forward<F>(func), m1); } else { auto&& [m1] = std::forward<T>(val); std::invoke(std::forward<F>(func), std::forward<decltype(m1)>(m1)); } } //tests struct obj{int v;}; struct data{obj o;}; void ref(obj&){std::cout<<"&\n";} void cref(const obj&){std::cout<<"const&\n";} void temp(obj&&){std::cout<<"&&\n";} int main(){ data d{}; apply1(ref, d); apply1(cref, d); //SHOULD NOT COMPILE apply1(temp, d); apply1(temp, std::move(d)); }

如您所见,
apply1
函数根据引用类型进行分支,因此看起来很奇怪。但如果没有这个,上面的测试将无法工作

问:

是否可以在不使用分支的情况下以更优雅的方式编写

apply1?但同时,上述测试应该有效

	

在 C++23 的
c++ c++20 structured-bindings
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.