2011-09-26 58 views
3

我正在做一些数值模拟,它很好地超载载体上的操作(类似于valarrays)。例如,我可以写C++广义操作员模板

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”和“A * B”都是相同类型(或有只有2个不同类型的?)

+0

我没有模板参数推导看看返回值(你不能在返回类型上重载) – sehe

回答

1

现在,上面的确,如果我使用运营商的情况 “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

+0

@Kerrek SB:糟糕,复制粘贴神器:)这不是必需的。谢谢 –

+0

我也想知道一个你不知道返回类型的操作的效用。你会用这个匿名媒介做什么?也许这很有道理,但我对此感到不安。 –

+0

@Kerrek SB:这就是auto的原因:)'auto v = A * B;' –

0

这可以通过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 
} 

不使用这种机制 - 并假定T和U不提供自己的机制 - 你不能做这样的事情。你只能处理T,U和返回类型都是相同类型的情况。但是,您可以处理原始类型 - 对于将诸如+之类的运算符应用于各种基本类型以找到提升类型的结果,存在Boost类型特征。

+0

谢谢,这也回答了我的问题! – andyInCambridge

+0

为什么'+'?它不应该是'*'吗? –

0

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