[英]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.