これがテストコードです:
#include <iostream>
#define OPTION 1
template<typename T>
class Base
{
public:
Base() : _x()
{std::cout<<"Base()"<<std::endl;}
Base(const T& source) : _x(source)
{std::cout<<"Base(const T& source)"<<std::endl;}
Base(const Base<T>& source) : _x(source.x)
{std::cout<<"Base(const Base<T>& source)"<<std::endl;}
public:
inline void set(const T& source)
{std::cout<<"Base::set(const T& source)"<<std::endl;
this->_x = source;}
inline T get() const
{std::cout<<"Base::get(const T& source)"<<std::endl; return _x;}
protected:
T _x;
};
template<typename T>
class Derived : public Base<T>
{
public:
Derived() : Base<T>()
{std::cout<<"Derived()"<<std::endl;}
Derived(const T& source) : Base<T>(source)
{std::cout<<"Derived(const T& source)"<<std::endl;}
Derived(const Derived<T>& source) : Base<T>(source)
{std::cout<<"Derived(const Derived<T>& source)"<<std::endl;}
public:
#if OPTION == 0
inline void set(const T& source)
{std::cout<<"Derived::set(const T& source)"<<std::endl;
this->_x = source;}
#endif
inline void set(const Base<T>& source)
{std::cout<<"Derived::set(const Base<T>& source)"<<std::endl;
this->_x = source.get();}
};
int main(int argc, char* argv[])
{
Derived<double> d;
double x = 4.5;
d.set(x);
return 0;
}
私にとっては同等ですがOPTION 0
、OPTION 1
そうではないので、その理由を理解したいと思います。
を使用OPTION 0
すると、main
呼び出し時d.set(x)
にコンパイラーはとの間Derived<T>::set(const T& source)
で選択できます。Derived<T>::set(const Base<T>& source)
もちろん、T x
彼はを選択しDerived<T>::set(const T& source)
ます。
を使用すると、を呼び出すOPTION 1
ときに、コンパイラにはとのどちらかを選択できると思います。main
d.set(x)
Base<T>::set(const T& source)
Derived<T>::set(const Base<T>& source)
Base<T>::set(const T& source)
ただし、コンパイラ(ここではGCC 4.6.3)は、を選択する代わりに、暗黙的にに変換x
してBase<T>
を呼び出しますDerived<T>::set(const Base<T>& source)
。
正常ですか?
そして、(コンストラクターを変更せずに)それを回避するための一般的な手法(存在する場合)はOPTION 0
何OPTION 1
ですか?