簡體   English   中英

構造函數,初始化列表以及g ++和clang中的不同行為

[英]Constructor, initializer list and different behaviour in g++ and clang

這是簡化的代碼:

#include <vector>

class VInitList
{
public:
    explicit VInitList(std::vector<int> v){}
};

int main()
{
    VInitList vil({{}});
}

並使用g ++ 5.2.1編譯a得到此錯誤:

 error: call of overloaded ‘VInitList(<brace-enclosed initializer list>)’ is ambiguous
     VInitList vil({{}});
                       ^
main.cpp:6:5: note: candidate: VInitList::VInitList(std::vector<int>)
     VInitList(std::vector<int> v){}
     ^
main.cpp:3:7: note: candidate: constexpr VInitList::VInitList(const VInitList&)
     class VInitList
           ^
main.cpp:3:7: note: candidate: constexpr VInitList::VInitList(VInitList&&)

當我看到編譯器錯誤時,我發現我錯誤地寫了{{}} (是的,不要對我有意義),但我仍然無法理解錯誤。 恕我直言,編譯器必須擺脫額外的{}或返回語法錯誤。

然后我試着編譯這個:

std::vector<int> v = {{{}}};

按預期工作。

但是std::vector<int> v = {{{}}}; 不做你的想法; 它使用一個int元素初始化一個向量,初始化為零。 這是因為int可以列表初始化:

int i{};   // assert(i == 0)

所以std::vector<int> v = {{{}}}; 被解析為:

std::vector<int> v = {{{}}};
                       ^-- int
                      ^-- initializer_list<int>
                     ^-- vector<int>

同樣,如果你寫

VInitList vil{{{}}};
               ^-- int
              ^-- vector<int>
             ^-- VInitList 

包含的vector<int>有1個元素,初始化為零。 (可以省略initializer_list<int>階段,因為vector(initializer_list<int>)構造函數是非explicit )。

所以VInitList vil({{}}); 可以解析為:

VInitList vil({{}});
               ^-- int
              ^-- vector<int>

或者作為

VInitList vil({{}});
               ^-- vector<int>
              ^-- VInitList

在第一種情況下, vector具有1個元素; 在第二種情況下,它是空的。 gcc拒絕你的代碼也是如此。

Clang只將它解析為前者; 我不確定哪個是正確的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM