C++11:编译器何时将 {} 视为 std::initializer_list,何时不视为?
C++11: when does compiler consider {} as std::initializer_list, and when doesn't?
我有一个快速示例:
#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;
}
Clang 会给出这个错误:
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
?
- In 'A a={1,'@'}'' :If {} is deduced as std::initializer_list, then how it's converted from std::initilizer_list to type A?
不,与std::initializer_list
无关。 a
只是 copy-list-initialized 来自 {1,'@'}
.
- In 'f({1,'#'});' When f requires a type A, does compiler implicitly generates an A object, or it converts from std::initializer_list to A?
还是和std::initializer_list
没有关系。函数参数是copy-list-initialized from {1,'#'}
.
- why when "g()" is a template, the template type deduction doesn't work to give a type A? Does "forward" help to convey the message from f to g, say that T is type A()?
因为这个属于non deduced context,模板参数T
无法推导导致编译错误
6) The parameter P, whose A is a braced-init-list, but P is not std::initializer_list or a reference to one:
和
when does compiler consider {} as std::initializer_list, and when doesn't?
当您将函数参数类型声明为 std::initializer_list
并将花括号列表作为参数传递时,将构造 std::initializer_list
。另一种情况是auto
,例如
auto x1 = {3}; // x1 is deduced as std::initializer_list<int>
auto x2{1, 2}; // after C++17, error: not a single element
// before C++17, it was std::initializer_list<int>
auto x3{3}; // after C++17, x3 is deduces as int
// before C++17 it was std::initializer_list<int>
顺便说一句:即使使用 auto
它也不适用于 {1,'@'}
,应该是 std::initializer_list<char>
还是 std::initializer_list<int>
?
我有一个快速示例:
#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;
}
Clang 会给出这个错误:
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
?
- In 'A a={1,'@'}'' :If {} is deduced as std::initializer_list, then how it's converted from std::initilizer_list to type A?
不,与std::initializer_list
无关。 a
只是 copy-list-initialized 来自 {1,'@'}
.
- In 'f({1,'#'});' When f requires a type A, does compiler implicitly generates an A object, or it converts from std::initializer_list to A?
还是和std::initializer_list
没有关系。函数参数是copy-list-initialized from {1,'#'}
.
- why when "g()" is a template, the template type deduction doesn't work to give a type A? Does "forward" help to convey the message from f to g, say that T is type A()?
因为这个属于non deduced context,模板参数T
无法推导导致编译错误
6) The parameter P, whose A is a braced-init-list, but P is not std::initializer_list or a reference to one:
和
when does compiler consider {} as std::initializer_list, and when doesn't?
当您将函数参数类型声明为 std::initializer_list
并将花括号列表作为参数传递时,将构造 std::initializer_list
。另一种情况是auto
,例如
auto x1 = {3}; // x1 is deduced as std::initializer_list<int>
auto x2{1, 2}; // after C++17, error: not a single element
// before C++17, it was std::initializer_list<int>
auto x3{3}; // after C++17, x3 is deduces as int
// before C++17 it was std::initializer_list<int>
顺便说一句:即使使用 auto
它也不适用于 {1,'@'}
,应该是 std::initializer_list<char>
还是 std::initializer_list<int>
?