簡體   English   中英

static_cast:轉換 function 模板 - 它們真的有效嗎?

[英]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,引文省略):

如果存在從eT的隱式轉換序列,或者如果用於 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.

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