引用折叠和元组

reference collapsing and and tuples

本文关键字:元组 折叠 引用      更新时间:2023-10-16

我正在尝试将参数包转换为引用,因为我的函数的某些参数可能是 r-/l- 值的混合。 有问题的函数:

//must return tuple
template <typename ...U>
std::tuple<U...> input(const char* format, U ...args) {
std::tuple<U...> t = std::tuple<U...> (args...);
//other code....
}

有一些我无法触及的测试代码... 这将调用我的函数:

template <typename... U>
std::tuple<U...> test_input(const char* fmt, U &&...inp) {
input(fmt, std::forward<U>(params)...);
//other stuff...
}

和 2 个测试对象(也是不可触碰的),它们删除了复制/移动构造函数A()B()。 如:

A(const A &) = delete;            //same for B
A &operator=(const A &) = delete; //same for B

如果我按原样调用该函数,我将收到"已删除的复制构造函数"或"已删除的构造函数"错误。例如:

test_input("blah blah", 1, i, "a", std::string("a"), A(123) B("string"));

问题是它可以是 r-/l 值的任何组合,我不知道如何将它们转换为所有引用

我知道我需要参考参数。我尝试使用std::forwardstd::forward_as_tuplestd::make_tuple,以及将第二个参数更改为inputU & ...argsU &&...args

我也明白我需要使用引用折叠:

  • A& & 成为 A&
  • A& && 成为 A&
  • A&& 成为 A&
  • A&
  • & && 成为 A&&

我尝试使用第一和第三条规则将任何内容转换为一种A&,但我仍然收到错误,例如:call to deleted constructor of 'B'expects an l-value for 2nd argument

如果我的问题不清楚 - 如何将argsinput的第二个参数转换为引用元组?

我想你想做这样的事情:

#include <tuple>
#include <string>
//must return tuple
template <typename ...U>
std::tuple<U&&...> input(const char*, U&&...args) {
return std::tuple<U&&...>(std::forward<U>(args)...);
//other code....
}
template <typename... U>
std::tuple<U&&...> test_input(const char* fmt, U &&...inp) {
return input(fmt, std::forward<U>(inp)...);
//other stuff...
}
struct A {
A(int) { }
A(const A &) = delete;            //same for B
A &operator=(const A &) = delete; //same for B
};
struct B {
B(const char *) { }
B(const B &) = delete;            //same for B
B &operator=(const B &) = delete; //same for B
};
int main() {
int i = 1;
test_input("blah blah", 1, i, "a", std::string("a"), A(123), B("string"));
}

[现场演示]