RValue が暗黙の変換を許可しないという問題に遭遇しました。私の質問は、この制限を「バイパス」するのにどの実装が適しているかです。
問題を説明するためのコード例を次に示します。
template<typename myVal>
class ITestClass
{
public:
virtual void myFunc(myVal item) = 0;
virtual myVal myFunc1() = 0;
};
class CTestClass : public ITestClass<int>
{
public:
void myFunc(int item) { }
int myFunc1() { return 0; }
};
template <typename T>
inline int CallFunction(std::shared_ptr< ITestClass<T> > ptrBase)
{
return 0;
}
inline std::shared_ptr< ITestClass<int> > GetBase()
{
return std::make_shared<CTestClass>();
}
std::shared_ptr< ITestClass<int> > ptrBase = std::make_shared<CTestClass>();
std::shared_ptr< CTestClass > ptrDerived = std::make_shared<CTestClass>();
CallFunction(ptrBase); // WORKS
CallFunction(GetBase()); // WORKS
CallFunction(std::make_shared<CTestClass>()); // ERROR
CallFunction(ptrDerived); // ERROR
RValue を使用できるが、関数がベースを必要とし、パラメーターが派生であるすべての呼び出しは失敗します。
オプション1
問題を修正するオプション 1:
CallFunction(std::static_pointer_cast< ITestClass<int> >(std::make_shared<CTestClass>()));
CallFunction(std::static_pointer_cast< ITestClass<int> >(ptrDerived));
このオプションでは、ユーザーは関数を呼び出す前に派生をベースにキャストする必要があります。これは、呼び出し元が変換の実際の基本型 (つまり、具体的なテンプレートのインスタンス化の基本型) を知る必要があるため、目的に反します。
オプション 2
問題を修正するためのオプション 2: (テンプレートを変更し、CallFunction をいくつか変更します)
template<typename myVal>
class ITestClass
{
public:
typedef myVal class_data_type;
virtual void myFunc(myVal item) = 0;
virtual myVal myFunc1() = 0;
};
class CTestClass : public ITestClass<int>
{
public:
void myFunc(int item) { }
int myFunc1() { return 0; }
};
template <typename T>
inline int CallFunction(std::shared_ptr<T> ptrBase)
{
static_assert(std::is_base_of<ITestClass<typename T::class_data_type>, T>::value, "Class needs to derive from ITestClass"); // some example of type checking
return 0;
}
CallFunction(std::make_shared<CTestClass>()); // now works as normal
CallFunction(ptrDerived); // now works as normal
呼び出し元は現在 RValue に課せられている制限を知らないため、オプション 2 の方が気に入っていますが、誰かが間違ったパラメーターを渡した場合に混乱を解消する十分な型チェック static_asserts があるかどうかはわかりません。
質問
オプション 2 に何か問題があると思いますか、それともオプション 1 の方が良いルートですか?
SFINAE を使用して型安全性をきれいにする方法はありますか?