【问题标题】:reference collapsing and and tuples引用折叠和和元组
【发布时间】:2016-12-10 20:10:47
【问题描述】:

我正在尝试将参数包转换为引用,因为我的函数的某些参数可能是 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 &amp; ...argsU &amp;&amp;...args

我也明白我需要使用参考折叠:

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

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

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

【问题讨论】:

  • 为什么您的input 方法不将U&amp;&amp;... 仅作为参数U...?您是否也考虑过在您的input 方法中使用std::forward_as_tuple
  • @W.F.使用U&amp;&amp;...,我得到call to implicitly-deleted copy constructor of std::tuple&lt;B&gt; std::forward_as_tuple,当我为这两个示例运行test_input("blah", B("string")); 时,我得到no viable conversion from tuple&lt;B &amp;&amp;&gt; to tuple&lt;B&gt;

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


【解决方案1】:

我想你想做这样的事情:

#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]

【讨论】:

  • 非常感谢!这是我对std::tuple&lt;U&amp;&amp;...&gt; 的声明。我试图调试分配给std::tuple &lt;U ...&gt; 的值,没想到要检查元组的类型!
猜你喜欢
  • 2020-09-15
  • 2018-12-24
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 2015-03-29
  • 2017-08-14
  • 2015-04-19
  • 1970-01-01
相关资源
最近更新 更多