プロセッサレジスタとその操作のプレースホルダーを実装できるクラス階層を見つけようとしています。また、実行時に定数を折りたたむことができるようにする必要があります。簡単にするために、ここでは乗算という1つの演算のみを見ていきます。プレースホルダーと定数は、均一にアクセスできる必要があります。つまり、共通の基本クラスを持っている必要があります。
以下のコードは、次のクラスを定義します。
class A
:プレースホルダー(レジスター)と定数の基本クラス
class B
:レジスターのプレースホルダー(その構造はその名前を保持します)
class C
:すべての定数のベース
class CI
: int
定数
class CF
: float
定数
#include <iostream>
#include <memory>
#include <cassert>
class A {
public:
virtual ~A(){}
};
class B : public A {
};
class C : public A {};
class CI : public C {
public:
typedef int Type_t;
int getValue() {return 1;}
};
class CF : public C {
public:
typedef float Type_t;
float getValue() {return 1.1;}
};
typedef std::shared_ptr<A> Aptr;
typedef std::shared_ptr<B> Bptr;
typedef std::shared_ptr<C> Cptr;
typedef std::shared_ptr<CI> CIptr;
typedef std::shared_ptr<CF> CFptr;
template<class T, class T2> struct promote {};
template<> struct promote<float,int> { typedef float Type_t; };
template<> struct promote<float,float> { typedef float Type_t; };
template<> struct promote<int,float> { typedef float Type_t; };
template<> struct promote<int,int > { typedef int Type_t; };
template<class T1, class T2>
typename promote<typename T1::element_type::Type_t,
typename T2::element_type::Type_t>::Type_t
mul_const( const T1& c1 , const T2& c2 )
{
std::cout << c1->getValue() * c2->getValue() << "\n";
return c1->getValue() * c2->getValue();
}
template<class T>
std::shared_ptr<T> get(const Aptr& pA) {
return std::dynamic_pointer_cast< T >( pA );
}
Aptr create_A(float f) { return std::make_shared<A>(); }
Aptr create_A(int i) { return std::make_shared<A>(); }
Aptr mul_const( const Cptr& cp1 , const Cptr& cp2 )
{
if (auto c1 = get<CI>(cp1))
if (auto c2 = get<CF>(cp2)) {
return create_A( mul_const(c1,c2) );
}
if (auto c1 = get<CF>(cp1))
if (auto c2 = get<CI>(cp2)) {
return create_A( mul_const(c1,c2) );
}
if (auto c1 = get<CI>(cp1))
if (auto c2 = get<CI>(cp2)) {
return create_A( mul_const(c1,c2) );
}
if (auto c1 = get<CF>(cp1))
if (auto c2 = get<CF>(cp2)) {
return create_A( mul_const(c1,c2) );
}
assert(!"oops");
}
Aptr mul( const Aptr& pA1, const Aptr& pA2 )
{
if (auto c1 = get<C>(pA1))
if (auto c2 = get<C>(pA2))
{
return mul_const(c1,c2);
}
}
int main()
{
Aptr pA1( new CF );
Aptr pA2( new CI );
Aptr result = mul( pA1, pA2 );
}
上記のコードで私が抱えている問題は関数Aptr mul_const( const Cptr& cp1 , const Cptr& cp2 )
です。基本的に、定数タイプのすべての可能な組み合わせに対するタイプの切り替えが含まれています。それは動作しますが、これがよりエレガントに実行できるかどうか知りたいですか?