Clang和GCC之间的区别

Clang和GCC之间的区别

本文介绍了const auto std :: initializer_list Clang和GCC之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我想了解当结合初始化列表和 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之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 09:11