我有一个快速的示例:C++ 11:编译器何时将{}视为std :: initializer_list,何时不会?
#include <utility>
using namespace std;
struct A{
int i;
char c;
};
void f(const A&){}
template<class T>
void g(T&& t)
{
f(forward<T>(t));
}
int main() {
A a={1,'@'};//OK
f({1,'#'});//OK
g({1,'@'});//Compilation error
return 0;
}
锵会给这个错误:
testArray.cpp:16:5: error: no matching function for call to 'g' g({1,'@'});//fix: g<A>({1,'@'}) ^ testArray.cpp:9:6: note: candidate template ignored: couldn't infer template argument 'T' void g(T&& t) ^
我的问题是:
在
A a={1,'@'};
,如果{}
推导为std::initializer_list
那么它是如何从std::initilizer_list
转换为A
?在
f({1,'#'});
,当f
需要类型A
,并编译器隐式地产生A
对象,或者它从std::initializer_list
转换为A
?为什么当
g()
是模板时,模板类型扣除是否不起作用以给出类型A
?std::forward
是否有助于将消息从f
传送到g
,比如说T
是A
类型?
这在C++ 17中有所变化,所以当你说“C++ 11”时,你真的指C++ 11,还是一般意思是“现代C++”? –
对于情况3,这可能起作用:'g(A {t,'@'});'因为正确的类型扣除应该通过临时发生。 – NameRakes
@JerryCoffin注意到[C++ 17的变化被认为是由于缺陷](http://stackoverflow.com/q/31301369/1708801),所以在最近的编译器中,他们将它们应用到C + 11和C++ 14。虽然在这方面有一段时间不一致。 –