次の簡単な例を考えてみましょう
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;
}
Clangでコンパイルすると、次のエラーが発生します
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 や Intel iclc など、他のコンパイラでも同様のエラーが生成されます。
と を削除するoperator int
とoperator bool
。正常にコンパイルされ、期待どおりに動作します。それらの 1 つだけを削除する場合、つまりテンプレート オペレータを保持して と言うとoperator int
、非テンプレート バージョンが常に選択されます。
私の理解では、テンプレートと非テンプレートのオーバーロードされた関数が完全に一致するか、両方が同じ変換シーケンスを必要とするという意味で等しい場合にのみ、非テンプレート バージョンが優先されます。ただし、この場合、コンパイラーはオペレーター・テンプレートを完全に一致していると見なしていないようです。そして、bool
とint
オーバーロードの両方が存在する場合、当然、それらはあいまいであると見なされます。
要約すると、私の質問は、この場合、オペレーター テンプレートが完全に一致していると見なされないのはなぜですか?