强制通用方法名

Enforcing Common Method Names

本文关键字:方法      更新时间:2023-10-16

注意:这是一个后续问题。

我有一组模板类,它们使用完全不同的数据类型,以完全不同的方式做完全不同的事情。但是,它们确实共享通用的方法名。例如,Get(), Set(), Resize()等是所讨论的每个类的有效方法。此外,它们以相同的顺序接受参数。这允许在每个类上使用一般化的非友元、非成员函数。一个简单的例子:

template <typename Class, typename Datatype>
void Insert(const Class<Datatype>& Object, const std::size_t Index, const Datatype Value)
{
    Object.Resize(Object.Size() + 1);
    for (std::size_t CurrentIndex = Object.Size() - 1; CurrentIndex > Index; CurrentIndex--)
    {
        Object.Set(CurrentIndex, Object.Get(CurrentIndex - 1));
    }
    Object.Set(Index, Value);
}

现在,我只是依靠我自己的记忆来正确定义所有适当的方法。是否有一种方法可以让编译器强制执行正确方法的定义?如果没有,有没有更好的方法?

你正在寻找的东西被称为"概念",它曾经是c++ 0x中的一个特性,但从新标准中删除了。

有一些c++ 03的实现,但它们更难使用,可能不值得麻烦。例如Boost Concept Checking

gcc也有——enable-concept-check选项,尽管我不完全确定如何与用户代码一起工作。

编译器已经通过拒绝为不提供必要方法的类型实例化模板来强制定义这些方法。

不幸的是,编译器对于不可实例化模板的错误信息通常很难破译。

您可以在注释中记录类型需求。看一看c++标准如何定义类型要求,如Assignable、CopyConstructible、EqualityComparable、LessThanComparable,以及标准容器中的类型要求。

编译器将通过不编译任何对不存在的函数的调用来强制执行正确的接口;也许问题是错误消息太过神秘?

可以定义一个基类,它将所需的接口声明为非虚函数。基类函数没有定义(除非有一个带有默认实现的可选函数)。

然后,如果模板实参派生自这个基类,则实现所需函数失败将导致链接错误(由于试图调用未定义的基类函数)。这可能比典型的与模板相关的编译错误更容易诊断。

你可以更进一步,包括一个编译时检查模板实参是否派生自基类;我将把它留给读者作为练习。或者最好只记录基类的用途,让用户自己决定是否使用它。

可以使用接口

参见这个问题:如何在c++中声明接口?