引用折叠和元组

时间:2016-12-10 20:10:48

标签: c++ reference tuples perfect-forwarding stdtuple

我正在尝试将参数包转换为引用,因为我的函数的一些参数可以是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-values的任何混合,我不知道如何将它们转换为所有参考

我知道我需要参考这些参数。我已尝试使用std::forwardstd::forward_as_tuplestd::make_tuple,并将第二个参数更改为inputU & ...argsU &&...args < / p>

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

  • A和&安培;成为A&amp;
  • A和&安培;&安培;成为A&amp;
  • A&安培;&安培; &安培;成为A&amp;
  • A&安培;&安培; &安培;&安培;成为A&amp;&amp;

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

如果我的问题不明确 - 如何将args input的第二个参数转换为引用元组?

1 个答案:

答案 0 :(得分:2)

我想你想做这样的事情:

#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"));
}

[live demo]