2
可以编写一个包含支持特定操作的任何类型的包装器,用于二进制操作的类型擦除
#include <iostream>
class Houdini
{
struct I_Houdini_Impl
{
virtual void foo_impl(int x) const = 0;
virtual ~I_Houdini_Impl() { }
};
template <typename T>
struct Houdini_Impl : I_Houdini_Impl
{
Houdini_Impl(T const & t) : m_t(t) { }
void foo_impl(int x) const { m_t.foo(x); }
T m_t;
};
public:
template <typename T>
Houdini(T const & t) : m_impl(new Houdini_Impl<T>(t)) { }
void foo(int x) const { m_impl->foo_impl(x); }
protected:
private:
std::unique_ptr<I_Houdini_Impl> m_impl;
};
class A
{
public:
void foo(int x) const { std::cout << "A::foo(" << x << ")" << std::endl; }
};
class B
{
public:
template <typename T>
char foo(T const & t) const { std::cout << "B::foo(" << t << ")" << std::endl; return 'B';}
};
void houdini()
{
A a;
B b;
Houdini ha(a);
Houdini hb(b);
ha.foo(7);
hb.foo(8);
}
我可以在支持可称为王氏一个int一个const-方法foo的霍迪尼级包裹任何事情,如果无论它是一个普通的成员函数(如类A)或函数模板(如B类)(现在让我们忽略Houdini应该展示价值语义)。到目前为止这么好,但我想要做的是编写一个支持二进制操作的包装器,例如写一个可以接受任何类型的包装,你可以说,只要包装的对象可以被添加,并返回从将包裹返回对象添加任何两种包装:如果我知道
class A { };
class B { };
class C { };
C operator+(A, B) { return C(); }
class Randi
{
public:
template <typename T> Randi(T) { }
/* magic stuff goes here */
};
void randi()
{
A a;
B b;
Randi ra(a);
Randi rb(b);
Randi rc = ra + rb;
// rc is a Randi-object that wraps an object of type C
}
事先什么类型我要去存储我可以通过写访问来做到这一点,但这正是我所做的而不是想要做的。我需要解开这两个对象,试着在两个打开的对象上调用operator +并重新包装结果,但我无法弄清楚如何做到这一点。
我会说,与模板和魔术这可以解决,但我不够聪明,知道如何。 – 2013-03-13 14:10:23
根据你目前的描述,我想你可能会走运。确定使用'operator +'的哪些可能的重载将需要编译时知道所涉及的类型,但是您已经专门擦除了该类型的信息。如果两个操作数必须是相同的类型,您可能可以做到这一点。 – 2013-03-13 17:13:26