[英]static_cast : Conversion function templates - are they really working?
據我閱讀static_cast以下代碼應該可以工作:
#include <iostream>
#include <string>
class ConvSample
{
public:
template<typename T>
constexpr operator T(){
return {};
}
};
int main()
{
ConvSample aInst;
int i = aInst;
std::cout << i << "\n";
std::string str = static_cast<std::string>(aInst);
std::cout << str << "\n";
return 0;
}
它與 Clang 等一些編譯器完美配合。 但例如 MSVC 或 ICC 不是。
請參閱編譯器資源管理器
一般來說,他們抱怨由 std::string 提供的構造函數不真正工作引起的一些歧義。
此外,如果我在 gcc 上打開 Wconversion,我會遇到分段錯誤?!
代碼有問題嗎? 這些錯誤只是編譯器錯誤嗎? 如果我將代碼更改為不使用模板,它會很好地工作: Compiler Explorer
不幸的是,標准在這里含糊不清([expr.static.cast]/4,引文省略):
如果存在從
e
到T
的隱式轉換序列,或者如果用於 object 的直接初始化或從e
引用類型T
的重載決議將找到至少一個可行的 function,則表達式e
可以顯式轉換為類型T
[…] [T] 結果 object 是從e
直接初始化的。 […]
這兩個啟用條件都成立:有一個隱式轉換序列(由所需的轉換 function 調用組成),並且有幾個可行的直接初始化函數(因為對於std::string
構造函數)。
然而,只有隱式轉換序列的復制初始化,它拒絕將ConvSample
轉換為(比如說) const char*
然后轉換為std::string
,它提供了一種生成std::string
的明確方法:它特別尋找目標類型的轉換函數,雖然它允許轉換為(比如) const std::string&
,但常見的實現並不解釋這意味着轉換 function 模板也應該為該類型實例化並變得模棱兩可。
最終要求的直接初始化在std::string
的 5 個單參數構造函數中是不明確的(6 個用於std::string_view
類類型): ConvSample
當然可以轉換為它們中的任何一個的參數類型相同的“成本”。
接受這一點的編譯器正在應用復制初始化規則(但仍允許explicit
轉換)。 那些拒絕它的人正在應用直接初始化,我相信這是目前的措辭所要求的。 僅在 CWG242 的C++17中引入了對隱式轉換序列的引用,顯然該領域的實現分歧仍然存在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.