C++ c++;广义算子模板

C++ c++;广义算子模板,c++,templates,operators,overloading,C++,Templates,Operators,Overloading,我正在做一些数值模拟,在那里可以很好地重载向量上的操作(类似于数组)。例如,我会写作 template <typename T> vector<T> operator*(const vector<T>& A, const vector<T>& B){ //blah blah } 模板 向量运算符*(常数向量和A、常数向量和B){ //废话 } 但是,如果我想对这个模板进行泛化,以便处理两种不同类型的向量,并(可能)返回第三

我正在做一些数值模拟,在那里可以很好地重载向量上的操作(类似于数组)。例如,我会写作

template <typename T>
vector<T> operator*(const vector<T>& A, const vector<T>& B){
   //blah blah
}
模板
向量运算符*(常数向量和A、常数向量和B){
//废话
}
但是,如果我想对这个模板进行泛化,以便处理两种不同类型的向量,并(可能)返回第三种类型,该怎么办?也就是说,我想写作

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是不同的类型,并返回另一个不同的类型,那么上述操作确实有效。但是,如果A和B是同一类型,则不起作用。当然,我可以为每个组合定义不同的模板(即仅T、或仅T和U、或T、U和V),但这看起来很难看。是否有一种方法可以使用上面给出的T、U和V变体的单个模板表达式,即使“a”、“B”和“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
}

HTH

这可以在具有decltype的C++0x中工作

template <typename T, template U> 
vector<decltype(declval<T>() + declval<U>())> 
operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}
模板
矢量
运算符*(常数向量和A、常数向量和B){
//废话
}

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

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

我不需要模板参数推断查看返回值(不能在返回类型上重载)@Kerrek SB:Oops,copy-paste artifact:)它不需要。ThanksI还想知道一个返回类型未知的操作的实用性。你将如何处理这个匿名向量?也许这是有道理的,但我对此感到不安。@Kerrek SB:这就是汽车的用途:)
auto v=A*B@Kerrek SB:例如,一个张量可能与一个向量收缩,生成一个矩阵。(无可否认,我可以用一个广义张量类来表示所有3种类型。)@Armen:嗯,是的,但是你怎么处理
v
?不能将其传递到期望使用特定类型向量的普通函数中。基于模板迭代器的算法可能是您唯一的选择…谢谢,这也回答了我的问题!为什么
+
?它不应该是
*
template <typename T, template U>
vector<decltype(T()*U())> operator*(const vector<T>& A, const vector<U>& B)  
{
   //blah blah
}
template <typename T, template U> 
vector<decltype(declval<T>() + declval<U>())> 
operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}