クランでコンパイルすると、それはオーバーロード変換演算子テンプレート
test.cpp:11:12: error: conversion from 'C' to 'double' is ambiguous
double x = c;
^ ~
test.cpp:4:5: note: candidate function
operator int() {return 1;}
^
test.cpp:5:5: note: candidate function
operator bool() {return false;}
^
test.cpp:3:27: note: candidate function [with T = double]
template <typename T> operator T() {return 0.5;}
^
1 error generated.
他のコンパイラは同様のエラー、例えば、GCCおよびインテルICLC
を生成し、次のエラーが発生しますstruct C
{
template <typename T> operator T() {return 0.5;}
operator int() {return 1;}
operator bool() {return false;}
};
int main()
{
C c;
double x = c;
std::cout << x << std::endl;
}
次の簡単な例を考えてみましょう
operator int
とoperator bool
を削除した場合。それは正常にコンパイルされ、期待どおりに動作します。それらのうちの1つだけを削除すると、それはテンプレート演算子を保持し、operator int
と言うと、テンプレート以外のバージョンが常に選択されます。
私の理解では、テンプレートと非テンプレートオーバーロード関数は、彼らは両方とも完全に一致しているか、その両方が同じ変換シーケンスを必要とするという意味で等しい場合にのみ、非テンプレートバージョンが優先されるということです。ただし、この場合、コンパイラは演算子テンプレートを完全一致として認識しません。 bool
とint
の両方のオーバーロードが存在する場合、当然、それらはあいまいとみなされます。要約すると
、私の質問は、なぜオペレータテンプレートがこの場合は完全に一致するとはみなされないということでしょうか?
標準のあなたの「変わった読書」は非常に面白く、実際にはかなり意味があります。私が正しく理解すれば、演算子intがテンプレートより優れているかどうかは、どちらがF1で、どちらがF2であるかによって決まります。 F1 = op int、F2 = opと考えると、箇条書き3では、F1がF2より優れていると判断して停止します。しかし、F1 = op 、F2 = op intと考えると、弾丸2ではF1が良いと判断し、停止します。しかし、3つがある場合、op intとop boolはもはや他のものよりも優れていないので、あいまいではありません –