使用模板扩展C ++中的类方法

问题描述

与其他语言相反,定义后不能扩展C ++类。 这就是为什么自由函数优于成员函数的原因,因为自由函数是扩展类行为的更通用的方法

同时,点语法(仅用于成员函数)可以具有一些符号上的优势,例如,当某个对象比函数调用中的其他参数“重要”时。

例如,

allocator a;
a.allocate(n); // vs. allocate(a,n);

这在语言上产生了张力。 (在早期的C ++中,这种紧张导致了the肿类的创建。)

在最佳情况下,区别在于语法。 在最坏的情况下,使用点的期望语法会强制在类内部定义方法(存在通过包含大量成员函数而使类变大的风险)。

到目前为止,这就是C ++,我们习惯于此。

但是,在某些情况下有一个漏洞。 问题是这个漏洞是否经常被利用,或者是否会在以后造成问题。

事实是,可以通过打开模板成员函数来模拟类的扩展。

例如:

struct A{
    void f(int n) const{...}
    void g(std::string s) const{...};
};

“成员” g无法扩展以使这项工作A a; a.g(42)。 但是,可以这样做使语法起作用:

struct A{
    void f(int n) const{}
    template<class T> void g(T t) const; // this can be even customized by a user of the library
};

// this can be defined anywhere down the road (but before `A::g<T>` is instantiated I think).
template<> void A::g<int>(int t) const{}
template<> void A::g<std::string>(std::string t) const{}

该扩展名不是通用的,在这种情况下,任何扩展名都必须具有固定的名称(和一个参数),但仍然感觉像是一个扩展名。

除了丑陋的类模板代码外,使用这种技术扩展类还有什么问题吗?

在一般情况下这并不简单,但是甚至可以扩展该技术以定制我认为的不同返回类型(在这里我使用void为简单起见,另一种简单情况是当返回类型为{{1} }本身。)

我可以看到的一个问题是部分专业化可能非常困难。 另一个问题是,实例化的顺序可能会出现问题,需要在首次使用(?)之前定义自定义项。

自定义命名函数并不是很令人印象深刻。 但是可以自定义其他功能,例如T。实际上,这就像是从类外部进行重载,这是正常方式无法实现的。

解决方法

除了丑陋的类模板代码外,使用这种技术扩展类还有什么问题吗?

不,它被称为“成员模板”,在C ++中是完全有效的东西。

更新

我知道这是有效的。我想知道这是否是经常使用的技术。

我个人从来没有经常使用它。通常,一直在决定将整个类实现为模板,而不是专注于单个功能。但同时,我相信这类事情取决于您要达到的目标以及您的个人品味。我的意思是它是语言的功能,所以为什么在感觉合适时不使用它。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...