std :: forward无法转换括号括起来的初始化程序列表

时间:2018-11-07 13:36:33

标签: c++ templates variadic-templates variadic-functions forward

为什么struct screen无法正确初始化框架结构?

我想要初始化屏幕结构并直接直接初始化2帧结构。

#include <iostream>
#include <sstream>
#include <cstring>

#define ESC "\033"

struct frame {
  public:
    frame(unsigned int w, unsigned int h) :
      m_w(w),
      m_h(h) {}

  private:
    unsigned int m_w, m_h;
};

struct screen {
  public:
    template<typename ... Args>
      screen(Args && ... args0, Args && ... args1) :
        m_f0(std::forward<Args>(args0)...),
        m_f1(std::forward<Args>(args1)...) {}

  private:
    frame m_f0, m_f1;
};

int main() {
  frame f = {16, 16};

  screen s = {f, {16, 16}};

  return 0;
}

1 个答案:

答案 0 :(得分:2)

{16, 16}没有类型。如果用于上下文中以某种类型初始化某些事物,它将初始化该事物。

构造函数参数具有类型。推导的模板构造函数参数从传递的参数中获取其类型。但是{16,16}没有类型,因此它不能从缺少类型的事物中推断出类型。

您的第二个问题是:

  template<typename ... Args>
  screen(Args && ... args0, Args && ... args1) :
    m_f0(std::forward<Args>(args0)...),
    m_f1(std::forward<Args>(args1)...) {}

C ++在这里不会为您推断Args...。仅当它是函数调用中的最后一个参数时,它才会推断出一个参数包,这里的Args...既是最后一个也不是最后一个,因此不会被推导。

现在您可以在某种程度上使用make from tuple

template<class...Args0, class...Args1>
screen( std::tuple<Args0...> args0, std::tuple<Args1...> args1 ):
  m_f0(std::make_from_tuple<frame>(std::move(args0))),
  m_f1(std::make_from_tuple<frame>(std::move(args1)))
{}

可以使您更接近(但距离不够近)。在呼叫站点,您可以执行以下操作:

screen s = {std::forward_as_tuple(f), std::forward_as_tuple(16, 16)};

它现在应该可以工作了。

这使用,但是make_from_tuple可以实现到in C++14