将一包转发引用包装成元组
Wrap a pack of forwarding references in a tuple
我具有这样的函数
template <typename... Args> void foo(Args&&... args);
我需要在最后添加一个带有默认参数的额外参数。由于包装需要最后一次,我正在考虑将功能更改为
template <typename... Args> void foo(std::tuple<Args&&...> args,
const std::string& name = {});
问题是,通过tuple
中的参数的最佳方法是什么。我的理解是,在std::tuple<Args&&...>
中,Args
不再转发参考文献,而是严格的RVALUE参考。如何获得args
包裹的CC_4的转发参考行为,例如接受std::forward_as_tuple
并保留单个元组元素的参考类型。另外,在这里通过元组的最佳方法是什么,
std::tuple<Args&&...> args
或
const std::tuple<Args&&...>& args
或
std::tuple<Args&&...>&& args
?
我需要在功能内的元组元素上使用std::forward
,还是简单地使用std::get
?
我的理解是,在
std::tuple<Args&&...>
中,Args
不再转发参考文献
正确。
,但严格rvalue参考
是的,除非明确指定Args
,否则在这种情况下参考折叠可以将它们变成LVALUE参考,即foo<int&>(...)
将导致Args&& -> int& && -> int&
。
什么是通过元组传递参数的最佳方法。
取决于foo
的预期用法。如果您不需要确切知道Args...
是什么,则可以逃脱:
template <typename Tuple>
void foo(Tuple&& args, const std::string& name = {});
在这种情况下,使用std::tuple_element_t<N, std::decay_t<Tuple>>
仍然可以访问单个类型。
如果您 do 想在foo
中知道Args...
(没有任何其他抽象级别),则您可能想推断出确切的类型,而无需任何参考:
template <typename.... Args>
void foo(std::tuple<Args...>&& args, const std::string& name = {});
请注意,如果某人在内部使用 std::forward_as_tuple
和lvalues and rvalues,则值类别将存储在Args
中,您仍然可以使用std::forward
转发这些参数(std::forward
IS 仅限于转发参考,只有思考,请思考它是有条件的演员)。
另外,在此处通过元组的最佳方法是什么
可能是前面建议的Tuple&&
。如果没有,则再次取决于用法。如果使用const std::tuple<Args...>&
,则通过查看std::get
的Overloads列表,您会发现值类别和constness将传播到std::get
的返回值(MODULO参考倒数)。std::tuple<Args...>&&
也是如此。另外,使用后者,您必须使用元组rvalue作为参数(foo(std::forward_as_tuple(...), ...)
而不是foo(my_tuple, ...)
)。
替代解决方案是接受一个参数包,并检测最后一个参数是否可以受到const std::string&
的约束:
#include <string>
#include <utility>
#include <tuple>
#include <type_traits>
struct dummy {};
template <typename... Args>
void foo_impl(Args&&... args)
{
const std::string& s = std::get<sizeof...(Args) - 1>(std::forward_as_tuple(std::forward<Args>(args)...));
}
template <typename... Args>
auto foo(Args&&... args)
-> std::enable_if_t<std::is_constructible<std::string, std::tuple_element_t<sizeof...(Args), std::tuple<dummy, Args...>>>{}>
{
foo_impl(std::forward<Args>(args)...);
}
template <typename... Args>
auto foo(Args&&... args)
-> std::enable_if_t<!std::is_constructible<std::string, std::tuple_element_t<sizeof...(Args), std::tuple<dummy, Args...>>>{}>
{
foo_impl(std::forward<Args>(args)..., "default");
}
demo
- 考虑引用和常量的可变参数函数包装器
- 将对象传递给函数而不将其包装到 std::ref 中,而参数被指定为 const 引用
- 自定义引用包装器的常量正确性
- libfreenect c++包装中未定义的引用
- 对类型的非常量左值引用 - 使用类类型的参数时,目标C++包装器中的错误
- 引用包装器的向量,push_back失败?
- 返回对 std::函数包装的 lambda 中静态变量的引用会导致段错误
- 非默认可构造和 std::引用包装器替代项的序列化
- 如何在 C++14 中编写用于调用 Fortran 函数的通用包装器(按引用调用 --按值调用>)
- 如何在 Cython 中包装引用的 c++ 类
- 将一包转发引用包装成元组
- 如何将数据传递到引用包装器
- 访问向量 c++11 中的引用包装元素
- 从引用包装器构造引用包装器
- 引用包装的初始化程序列表
- c++:引用包装器和printf
- 常量引用包装器
- 如何使用右值引用包装指针
- 返回c++引用包装器
- 将基类的引用包装器的矢量转换为派生类的引用包装程序的矢量不能动态强制转换