簡體   English   中英

這是一個鏗鏘的bug還是我不了解的關於C ++的東西?

[英]Is this a clang bug or something I don't know about C++?

在看這個問題時,我用鏗鏘聲試了一下,陷入了一種奇怪的境地。 以下示例:

#include <string>

class ACP
{
public:
    ACP() {}
    operator const std::string() const  { return std::string(); }
    // operator std::string() const  { return std::string(); } <-- makes clang happy
};

void test()
{
   const ACP acp;
   auto a = (std::string)acp;
}

使用gcc在coliru上編譯好,但是沒有使用clang。 至少我看到這個例子沒有問題 - 這是clang中的錯誤還是有一個規則實際上解釋了clang錯誤和gcc是錯誤的?

clang的錯誤如下:

clang -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp:13:26: error: no viable conversion from 'const ACP' to 'std::__cxx11::basic_string<char>'
   auto a = (std::string)acp;
                         ^~~
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:421:7: note: candidate constructor not viable: no known conversion from 'const ACP' to 'const std::__cxx11::basic_string<char> &' for 1st argument
      basic_string(const basic_string& __str)
      ^
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:493:7: note: candidate constructor not viable: no known conversion from 'const ACP' to 'const char *' for 1st argument
      basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
      ^
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:515:7: note: candidate constructor not viable: no known conversion from 'const ACP' to 'std::__cxx11::basic_string<char> &&' for 1st argument
      basic_string(basic_string&& __str) noexcept
      ^
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:542:7: note: candidate constructor not viable: no known conversion from 'const ACP' to 'initializer_list<char>' for 1st argument
      basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
      ^
main.cpp:7:5: note: candidate function
    operator const std::string() const  { return std::string(); }
    ^
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:515:35: note: passing argument to parameter '__str' here
      basic_string(basic_string&& __str) noexcept
                                  ^
1 error generated.

但是我不明白為什么編譯器不能使用std::string的copy ctor。

簡化:

struct A {};
struct B { operator const A(); };
B b;
A a(b);

這是目標類型類型 A 直接初始化 ,因此枚舉A 候選構造函數 ,選擇A的所有構造函數(包括隱式定義的復制和移動構造函數),並通過重載解析比較類對象的直接初始化 首先評估構造函數的可行性 ,這意味着嘗試構造從b (左值B )到其參數的隱式轉換序列 由於參數是引用( A const&A&& ),我們必須執行引用初始化 我們可以初始化一個引用 A const& from b因為b可以轉換為rvalue A const ,而A const (目標引用的類型)和A const (目標函數的返回類型)是引用兼容的 (因為它們是相同的cv限定類型); 實際上,這是一個直接的參考綁定 我們無法初始化來自b的引用A&& ,因為A&& 具有A const 更少的cv資格 所以A::A(A const&)是唯一可行的構造函數並被選中。

據報道,這已經多次鏗鏘1 2 3但遺憾的是沒有被撿起來。

所有其他主要編譯器(gcc,ICC,MSVC)正確編譯代碼。

有趣的是,正如這里討論的那樣 clang在C ++ 03模式下正確編譯代碼。 如果我們通過抑制其移動構造函數強制A成為“C ++ 03樣式”類型,則clang將編譯生成的代碼:

struct A { A(A const&) = default; };
struct B { operator const A(); };
B b;
A a(b);

這表明也許clang被移動構造函數搞糊塗了。 它不應該,因為移動構造函數不可行; A&& a = b; 是無效的。

暫無
暫無

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

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