我有一个C++代码,在这里我比较了来自公共(public)母类Foo的不同类。如果两个类的类型不同,则比较始终为false。否则,它将比较特定于该类的一些内部数据。

我的代码如下所示:

class Bar;
class Baz;

class Foo
{
public:
    virtual bool isSame( Foo* ) = 0;
    virtual bool isSameSpecific( Bar* ){ return false; }
    virtual bool isSameSpecific( Baz* ){ return false; }
};

class Bar : public Foo
{
public:
    bool isSame( Foo* foo){ return foo->isSameSpecific(this); }
    bool isSameSpecific( Bar* bar){ return bar->identifier == identifier; }

    int identifier;
};

// and the same for Baz...

这很好用(我认为这是双重调度),我可以仅使用指向Bar的指针来比较BazFoo

但是现在出现了问题。我必须添加一个模板类:
template< typename T>
class Qux : public Foo
{
//...
};

问题是在Foo中,我无法为isSameSpecific声明方法Qux*,因为它是虚拟的和模板的。

问题:是否有任何巧妙的方法可以解决此问题?

最佳答案

这个问题真的没有解决方案:您需要
每个实例化的isSameSpecific函数
您使用的模板。 (换句话说,在Foo中:

template <typename T>
virtual bool isSameSpecific( Qux<T>* );

是非法的,但是:
virtual bool isSameSpecific( Qux<int>* );
virtual bool isSameSpecific( Qux<double>* );
//  etc.

不是。)

您也许可以摆脱创建摘要的麻烦QuxBase,并从中派生Qux<T>。最有可能的,
那只会把问题移到QuxBase,但是如果isSameSpecific不依赖于T的类型,例如
因为您可以定义一些规范的包含类型,所以它可能
可行。不了解QuxisSameSpecific,很难说。 (如果
如果Qux<T>::isSameSpecific应该始终返回false
实例化类型不同,例如,您可以键入
checkin QuxBase::isSameSpecific,然后转发到另一个
虚拟函数(如果类型相同)。

请注意,类似的问题会影响所有其他替代方式
以及实现多个分派(dispatch)。最后,你是
要求派发一组开放的类型,这意味着
可能无限多的不同功能。

编辑:

请注意:我假设您的isSame只是一个
例如,实际操作可能会更复杂。
您显示的实际代码显然属于我的建议
第二段;实际上,它甚至可以实现
没有多次 dispatch 。只需定义一个规范的“标识符”
类型,定义一个虚拟的getCanonicalIdentifier函数,然后
isSame中使用它:
bool Foo::isSame( Foo const* other ) const
{
    return getCanonicalIdentifier()
        == other->getCanonicalIdentifier();
}

就此而言,如果不同类型意味着isSame返回false(通常,如果isSame表示其外观,则返回false
一样),您也不需要双重调度:
bool Foo::isSame( Foo const* other ) const
{
    return typeid( *this ) == typeid( *other )
        && isSameSpecific( other );
}

派生的isSameSpecific将必须转换
指针,但是由于可以保证指针是相同的
作为this的类型,这是一种简单且安全的操作。

最后:如果类没有值语义(并且
如果涉及多态性,几乎可以肯定不应该),
像这样简单:
bool Foo::isSame( Foo const* other ) const
{
    return this == other;
}

可能就足够了。

但是,所有这些仅适用于isSame之类的东西。
如果您还有其他受影响的功能,请返回
达到我最初所说的。

关于c++ - 双重调度和模板类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16186608/

10-09 13:37