C++ std::forward无法转换括号内的初始值设定项列表
为什么结构屏幕不能正确初始化框架结构 我想要的是初始化screen结构,并直接初始化2个frame结构C++ std::forward无法转换括号内的初始值设定项列表,c++,templates,variadic-templates,variadic-functions,forward,c++17,c++11,C++,Templates,Variadic Templates,Variadic Functions,Forward,C++17,C++11,为什么结构屏幕不能正确初始化框架结构 我想要的是初始化screen结构,并直接初始化2个frame结构 #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) {}
#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;
}
#包括
#包括
#包括
#定义ESC“\033”
结构框架{
公众:
帧(无符号整数w,无符号整数h):
m_w(w),
m_h(h){}
私人:
无符号整数m_w,m_h;
};
结构屏幕{
公众:
模板
屏幕(Args&&…args0、Args&&…args1):
m_f0(标准::正向(args0),
m_f1(std::forward(args1)…{}
私人:
帧m_f0,m_f1;
};
int main(){
帧f={16,16};
屏幕s={f,{16,16};
返回0;
}
{16,16}
没有类型。如果在上下文中使用某个类型来初始化某个对象,它将初始化该对象
构造函数参数有一个类型。推断的模板构造函数参数从传递的参数获取其类型。但是{16,16}
没有类型,所以它不能从缺少类型的东西中推断出类型
你的第二个问题是:
template<typename ... Args>
screen(Args && ... args0, Args && ... args1) :
m_f0(std::forward<Args>(args0)...),
m_f1(std::forward<Args>(args1)...) {}
这会让你更接近(但距离不够近)。在呼叫站点,您可以执行以下操作:
screen s = {std::forward_as_tuple(f), std::forward_as_tuple(16, 16)};
现在它应该可以工作了
这使用了,但是
make\u from\u tuple
可以早到或实现。{16,16}
没有类型。如果在上下文中使用某个类型来初始化某个对象,它将初始化该对象
构造函数参数有一个类型。推断的模板构造函数参数从传递的参数获取其类型。但是{16,16}
没有类型,所以它不能从缺少类型的东西中推断出类型
你的第二个问题是:
template<typename ... Args>
screen(Args && ... args0, Args && ... args1) :
m_f0(std::forward<Args>(args0)...),
m_f1(std::forward<Args>(args1)...) {}
这会让你更接近(但距离不够近)。在呼叫站点,您可以执行以下操作:
screen s = {std::forward_as_tuple(f), std::forward_as_tuple(16, 16)};
现在它应该可以工作了
这使用了,但是
make_from_tuple
可以在或之前实现。带括号的init list没有类型,因此如果不指定模板要表示的类型,就无法将它们指定给模板。@NathanOliver屏幕s={f,f}代码>也不起作用。@DanielLangr正确{f,f}
是一个对象,所以它试图用它来推断参数,但不能,因为{f,f}
没有类型。@NathanOliver那么屏幕s(f,f)
呢?我的观点是,OP的问题在我看来不是关于带括号的init列表,正如您在副本中所建议的那样。这是关于多个参数包的。我建议看一下如何将两组参数转发给它的两个数据成员的构造函数。bracked-init-list没有类型,因此如果不指定模板要表示的类型,就不能将它们提供给模板。@NathanOliverscreen s={f,f}代码>也不起作用。@DanielLangr正确{f,f}
是一个对象,所以它试图用它来推断参数,但不能,因为{f,f}
没有类型。@NathanOliver那么屏幕s(f,f)
呢?我的观点是,OP的问题在我看来不是关于带括号的init列表,正如您在副本中所建议的那样。这是关于多个参数包的。我建议看看如何将两组参数转发给它的两个数据成员的构造函数。使用两个模板参数包不是更好吗,每个函数参数单独使用一个?在您的情况下,实际上并没有完美地转发16,16
,因为创建并转发了一个临时frame
。如果您没有C++17:。@DanielLangr修复,这个答案是相关的。请注意,在C++17中,make_from_tuple
返回一个不是临时对象的prvalue。因此,转发是完美的。在C++14/11中,它不是完美的,使它完美是一件非常麻烦的事。使用两个模板参数包,每个函数参数使用一个单独的模板参数包不是更好吗?在您的情况下,实际上并没有完美地转发16,16
,因为创建并转发了一个临时frame
。如果您没有C++17:。@DanielLangr修复,这个答案是相关的。请注意,在C++17中,make_from_tuple
返回一个不是临时对象的prvalue。因此,转发是完美的。在C++14/11中,它不是完美的,使它完美是一件非常麻烦的事。