问题描述
我想了解当结合初始化列表和 const auto 时,C ++ 11应该是正确的行为。对于下面的代码,我在GCC和Clang之间得到不同的行为,并想知道哪个是正确的:
#include < iostream>
#include< typeinfo>
#include< vector>
int main()
{
const std :: initializer_list< int> l1 = {1,2,3};
const auto l2 = {1,2,3};
std :: cout<< explicit:<< typeid(l1).name()<< std :: endl;
std :: cout<< auto:<< typeid(l2).name()<< std :: endl;
}
使用g ++编译输出为:
explicit:St16initializer_listIiE
auto:St16initializer_listIKiE
虽然clang ++编译版本产生:
explicit:St16initializer_listIiE
auto:St16initializer_listIiE
似乎GCC正在将 auto c $ c> std :: initializer_list< const int> ,而Clang生成 std :: initializer_list< int> 。 GCC版本创建一个问题,当我使用它来初始化 std :: vector 。所以下面的工作在Clang下,但为GCC产生一个编译器错误。
//在clang下编译,但对于GCC失败,因为l4
std :: vector< int& v2 {l2};
如果GCC生成正确的版本,那么似乎建议将各种STL容器扩展到对这些情况包括另一个列表初始化器重载。
注意:这种行为似乎在多个版本的GCC(4.8,4.9,5.2)和Clang(3.4和3.6)之间是一致的。
GCC错误。 [dcl.spec.auto] / p7(引用N4527):
/ code>,如同对于功能模板
模板< class U> void meow(const std :: initializer_list< U>);
给予呼叫 meow({1,2,3} code>。
现在考虑一下const auto l3 = {1,2,3}; (其中GCC正确地推导为 std :: initializer_list< int> )。在这种情况下的扣除被执行,如同对于功能模板
template< class U> void purr(std :: initializer_list< U>);
给予调用 purr({1,2,3} code>。
由于函数参数的顶级cv限定被忽略,所以显然应该产生相同的类型。 p>
[temp.deduct.call] / p1:
Deducing <$对 1 ,<$ c> P'( U $ c> 2 或 3 ,所有类型 int 的文本, code> int 。
I am trying to understand what the correct behavior of C++11 should be when combining initialization lists and const auto. I am getting different behavior between GCC and Clang for the following code and would like to know which is the correct one:
#include <iostream> #include <typeinfo> #include <vector> int main() { const std::initializer_list<int> l1 = { 1, 2, 3 }; const auto l2 = { 1, 2, 3 }; std::cout << "explicit: " << typeid(l1).name() << std::endl; std::cout << "auto: " << typeid(l2).name() << std::endl; }
Compiled with g++ the output is:
explicit: St16initializer_listIiE auto: St16initializer_listIKiE
While the clang++ compiled version produces:
explicit: St16initializer_listIiE auto: St16initializer_listIiE
It seems that GCC is turning the auto line into a std::initializer_list<const int> while Clang produces std::initializer_list<int>. The GCC version creates a problem when I use it to initialize a std::vector. So the following works under Clang but produces a compiler error for GCC.
// Compiles under clang but fails for GCC because l4 std::vector<int> v2 { l2 };
If GCC is producing the correct version then it seems to suggest that the various STL containers should be extended to include another list initializer overload for these cases.
Note: this behavior seems to be consistent across multiple versions of GCC (4.8, 4.9, 5.2) and Clang (3.4 and 3.6).
GCC bug. [dcl.spec.auto]/p7 (quoting N4527):
Thus, in const auto l2 = { 1, 2, 3 };, deduction is performed as if for the function template
template<class U> void meow(const std::initializer_list<U>);
given the call meow({1, 2, 3}).
Now consider the const-less case auto l3 = { 1, 2, 3 }; (which GCC correctly deduces as std::initializer_list<int>). Deduction in this case is performed as if for the function template
template<class U> void purr(std::initializer_list<U>);
given the call purr({1, 2, 3}).
Since top-level cv-qualification of function parameters are ignored, it should be obvious that the two deduction should yield the same type.
[temp.deduct.call]/p1:
Deducing P' (which is U) against 1, 2, or 3, all literals of type int, obviously yields int.
这篇关于const auto std :: initializer_list Clang和GCC之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!