簡體   English   中英

為什么這個用戶定義的轉換失敗了?

[英]Why is this user-defined conversion failing?

這段代碼失敗了,但我認為選擇的轉換函數應該是operator std::string()因為它比operator const char*()Foo -> const char* -> std::string需要更少的步驟( Foo -> std::stringFoo -> const char* -> std::string )。

struct Foo
{
    operator const char*();
    operator std::string();
};

void f(Foo foo)
{
    std::string s2(foo); // Error!
}

該標准規定轉換僅限於一個轉換序列,轉換僅適用於明確的轉換,為什么這些轉換失敗?

錯誤是:

error: call to constructor of 'std::string' (aka 'basic_string<char>') is ambiguous
    std::string s2(foo);
                ^  ~~~
note: candidate constructor
      basic_string(basic_string&& __str)
      ^
note: candidate constructor
      basic_string(const basic_string& __str);
      ^
note: candidate constructor
      basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
      ^
1 error generated.

要僅使用非顯式構造函數和用戶定義的轉換,您應該從foo 復制初始化 s2 ,而不是直接初始化它。 引用cppreference

直接初始化比復制初始化更寬松:復制初始化僅考慮非顯式構造函數和用戶定義的轉換函數,而直接初始化則考慮所有構造函數和隱式轉換序列。

試試這個:

std::string s2 = foo;

您現有的代碼正在調用std::string的構造函數,其對象類型為Foo 由於從foo到多個std::string構造函數的參數類型的有效轉換具有相同的轉換序列長度,因此會遇到歧義問題。

同時,雙方的轉換需要一個步驟:

  • foo - > char const*使用std::string::string(char const*)
  • foo - > std::string使用std::string::string(std::string&&)

第三個重載是需要考慮的選項重載結果,但是采用std::string&&的構造函數比采用std::string(std::string const&)的構造函數更好,如果它們是唯一選項則會被選中。

目前我不能輕易測試它,但我希望如此

std::string s3 = foo;

更喜歡通過std::string進行轉換。

錯誤很清楚。 生成錯誤的行包含std::string實例的構造函數,該實例具有使用const char*std::string& copy構造const char*有效構造函數。 兩者都需要使用您提供的轉換重載進行單個隱式轉換步驟,因此它的含義是模糊的。

顯式地轉換對象以調用預期的轉換 - 取決於你的內部邏輯, const char*構造函數可能“更便宜”,因為std::string轉換可能只返回std::string((const char*)this) 如果是這種情況,我甚至建議刪除std::string轉換器,因為它總是會導致模糊性,這種模糊性永遠不會更高效。

暫無
暫無

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

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