c++通用操作符模板

c++ generalized operator templating

本文关键字:操作符 c++      更新时间:2023-10-16

我正在做一些数值模拟,其中对向量(类似于值数组)进行重载操作是很好的。例如,我可以写

template <typename T>
vector<T> operator*(const vector<T>& A, const vector<T>& B){
   //blah blah
}

但是,如果我想泛化这个模板,以便作用于两种不同类型的向量,并(可能)返回第三种类型,该怎么办?例如,我想写

template <typename T, template U, template V>
vector<V> operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

现在,如果我在"a *B"的情况下使用操作符,其中a和B是不同的类型,并返回另一个不同的类型,则上述操作确实有效。但是,如果A和B是同一类型,则不起作用。当然,我可以为每个组合定义不同的模板(例如,仅T,或仅T和U,或T, U和V),但这看起来很难看。是否有一种方法可以使用上面给出的T,U和V的单一模板表达式,并使其工作,即使"a","B"answers"a *B"都是相同的类型(或只有两个不同的类型?)

现在,如果我在某种情况下使用操作符,上面的内容确实有效"A*B",其中A和B不同,返回不同的类型。

老实说,这没有意义。你的模板根本不能工作,因为V不能被推导出来,而且它是第三个模板参数。如果你写:

template <typename V, template T, template U>
vector<V> operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

这将"工作",但只有当你明确指定V,如

operator*<double>(A, B); //where A is vector<int> and B is vector<float>, for example

您肯定想返回一个vector<V>,其中V是表达式T()*U()的类型。这在c++ 11中是可以做到的,但在c++ 03中就不那么简单了(我的意思是,你最多只能做一些类型训练)。在c++ 11中是这样做的:

template <typename T, template U>
vector<decltype(T()*U())> operator*(const vector<T>& A, const vector<U>& B)  
{
   //blah blah
}

HTH

这可以在c++ 0x中使用decltype。

template <typename T, template U> 
vector<decltype(declval<T>() + declval<U>())> 
operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

如果不使用这种机制——并且假设T和U没有提供它们自己的机制——你就不能做这样的事情。您只能处理T、U和返回类型都是相同类型的情况。但是,您可以处理基本类型—对于将+等操作符应用于各种基本类型以查找提升的类型的结果,有一个Boost类型特性。

正如其他人指出的那样,您可以使用decltype来实现这一点。c++ 0x还提供了模板common_type,它推导出一种类型,所有模板参数都可以强制转换为该类型,而无需任何特定的算术操作。因此,如果实参类型没有重载操作符,也可以使用