c++ - 双重分派(dispatch)和模板类

标签 c++ templates double-dispatch

我有一个 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...

这很好用(我认为这是双重 dispatch ),我可以比较 BarBaz只有指向 Foo 的指针.

但是现在问题来了。我必须添加一个模板类:

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如果 实例化类型不同,例如,您可以键入 打卡QuxBase::isSameSpecific , 并转发给另一个 如果类型相同则为虚函数。)

请注意,类似的问题会影响所有替代方法 也实现多重分派(dispatch)。最后,你是 要求通过一组开放的类型进行调度,这意味着 可能有无限数量的不同功能。

编辑:

需要说明的是:我假设您的 isSame只是一个 例如,实际操作可能更复杂。 您显示的实际代码显然符合我的建议 第二段;事实上,它甚至可以实现 没有多次 dispatch 。只需定义一个规范的“标识符” 类型,定义一个虚拟 getCanonicalIdentifier功能,和 在 isSame 中使用它:

bool Foo::isSame( Foo const* other ) const
{
    return getCanonicalIdentifier() 
        == other->getCanonicalIdentifier(); 
}

就此而言,如果不同的类型意味着 isSame 返回 false(通常是这种情况,如果 isSame 表示它看起来的样子 像),你也不需要双重调度:

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++ - 双重分派(dispatch)和模板类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16186608/

相关文章:

c++ - 这是内存泄漏吗,如果不是,是否由标准保证?

c++ - 检查共享库是否与二进制文件兼容?

c++ - 如何在没有 Nvidia DLL 的情况下调试 OpenCV 程序?

c++ - 解释出这段代码?

Angular 2 : How to override components template?

html - 我应该编辑哪些 CSS 文件以在此模板中进行任何简单的颜色/样式更改?

c++ - 在 C++ 中专门化函数时调用函数的非专门化版本?

java - Java 的双向可扩展层次结构

java - 访客模式和双重 dispatch

c++ - 了解双重调度 C++