クラスに変換演算子関数テンプレートを書き込もうとしていますが、完全には理解できないコンパイルエラーが発生します。
class ABC { };
class BBC:public ABC { };
template <class T>
class TestPtr
{
public:
TestPtr(T* ptr=0)
: _pointee(ptr)
{ }
TestPtr(TestPtr& rhs)
{
this->_pointee = rhs._pointee;
rhs._pointee= 0;
}
template <class U> operator TestPtr<U>();
private:
T* _pointee;
};
template <class T> template <class U>
TestPtr<T>::operator TestPtr<U>()
{
return TestPtr<U>(this->_pointee); // if this line is changed to
//TestPtr<U> x(this->_pointee); // these commented lines, the
//return x; // compiler is happy
}
void foo (const TestPtr<ABC>& pmp)
{ }
int main() {
TestPtr<BBC> tbc(new BBC());
foo(tbc);
}
上記のコードにより、次のエラーが発生します
TestPtr.cpp: In member function ‘TestPtr<T>::operator TestPtr<U>() [with U = ABC, T = BBC]’:
TestPtr.cpp:38:9: instantiated from here
TestPtr.cpp:28:34: error: no matching function for call to ‘TestPtr<ABC>::TestPtr(TestPtr<ABC>)’
TestPtr.cpp:28:34: note: candidates are:
TestPtr.cpp:13:3: note: TestPtr<T>::TestPtr(TestPtr<T>&) [with T = ABC, TestPtr<T> = TestPtr<ABC>]
TestPtr.cpp:13:3: note: no known conversion for argument 1 from ‘TestPtr<ABC>’ to ‘TestPtr<ABC>&’
TestPtr.cpp:9:3: note: TestPtr<T>::TestPtr(T*) [with T = ABC]
TestPtr.cpp:9:3: note: no known conversion for argument 1 from ‘TestPtr<ABC>’ to ‘ABC*’
今私が困惑しているのは、コンパイラがreturnステートメントではTestPtr<ABC>::TestPtr(TestPtr<ABC>)
なくpickを試みていることです。TestPtr<ABC>::TestPtr(ABC *)
ただし、最初に目的のコンストラクターを使用して変数を作成してから値を返すと、正常に機能します。また、T*コンストラクターを無駄に明示的にしました。
g++とclang++の両方で試しましたが、同様の結果が得られました。誰かがここで何が起こっているのか説明してもらえますか?