簡體   English   中英

顯式轉換運算符模板的優先級和模糊性

[英]Priority and ambiguity of explicit conversion operator templates

我一直在我的項目中使用模板化的顯式轉換運算符,以實現類似自定義變體類型的顯式轉換。 再現我的問題的最小示例如下所示(在C ++ 14模式下):

#include <iostream>
#include <stdexcept>
#include <cmath>

using namespace std;

class A
{
        public:
        template<typename T> explicit operator T() const // 1
        {
                cout << "operator T" << endl;
                return T();
        }

        template<typename T> explicit operator const T&() const // 2
        {
                cout << "operator const T&" << endl;
                throw runtime_error("operator const T&");
        }

        template<typename T> explicit operator T&() // 3
        {
                cout << "operator T&" << endl;
                throw runtime_error("operator T&");
        }


};


int main(int, char**)
{
        try
        {
                const A& a = A();
                cout << abs(static_cast<double>(a) - 3.14) << endl;
        }
        catch (const runtime_error&)
        {

        }

        return 0;
}

我遇到的問題是為static_cast轉換選擇的運算符。 對於海灣合作委員會來說,這是一種預期的(1)案例。 輸出是:

operator T
3.14

但Clang拒絕使用以下輸出編譯它:

main.cpp:37:20: error: ambiguous conversion for static_cast from 'const A' to 'double'
            cout << std::abs(static_cast<double>(a) - 3.14) << endl;
                             ^~~~~~~~~~~~~~~~~~~~~~
main.cpp:10:32: note: candidate function [with T = double]
    template<typename T> explicit operator T() const
                                  ^
main.cpp:16:32: note: candidate function [with T = double]
    template<typename T> explicit operator const T&() const
                                  ^
1 error generated.

為什么Clang考慮轉換(2),當它顯然需要在轉換序列中進行額外的構造函數調用時,而(1)不會? 它是否正確(而GCC是錯誤的)這樣做?

static_cast執行隱式轉換或直接初始化。 在您的情況下,隱式轉換不可行,但直接初始化因為static_cast考慮了顯式構造函數和轉換函數 所以我的猜測是clang(在我看來是正確的)確定有兩種可能的直接初始化和相應的抱怨。 不知道GCC內部發生了什么,也許它默認為operator T()如果它可以找到一個,無論是否存在其他的。

暫無
暫無

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

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