在我的工作中,有几种模板数学类(例如矩阵)。
可以使用浮点数或双精度数(或其他数值类型,但就此而言,并不重要)来实现对象。
一个双重对象只能与另一个双重对象进行交互。为此,功能convert()是针对各种类型实现的,其实现方式与此类似:
Matrix<T2> convert(const Matrix<T1>& m, T2 dummy) {
// create a matrix with type T2 and cast m values into it
// retMatrix(i, j) = (T2)m(i,j)
}
您可以这样称呼它:
auto floatMatrix = convert(doubleMatrix, 0.f);
或更冗长:
auto floatMatrix = convert(doubleMatrix, float());
我想添加一个类似于下面的函数,它将使调用这些函数的方法更简洁(IMHO)
template <typename T, typename S>
auto convert(S&& s) -> decltype(convert(s, T())) {
return convert(s, T());
}
现在可以使用以下命令调用它们:
auto floatMatrix = convert<float>(doubleMatrix);
我的问题是我的函数签名很尴尬,我需要在decltype和实际函数主体中重复convert(s, T())
我该如何克服呢?
谢谢
编辑:
当前,我们没有使用c ++ 14
编辑#2:
Matrix类只是一个例子,有很多相关的类为其实现了convert()函数。他们每个人都已经“专业化”,就像下面答案中建议的一样(同时删除)。我想调整convert()的调用方式,而无需重新实现所有功能
编辑#3:
支持的类型显然不是仅float和double。请把我给的例子当作例子,而不是我要解决的实际问题
“虚拟”功能已经实现,我试图以最小的努力使其工作,而不是重构30个功能和所有用法
考虑到cpp14允许删除-> decltype()
杂物,我认为问题尚未解决。
答案 0 :(得分:1)
有些困惑为什么首先需要模板而不是函数重载:
Matrix<double> convert(const Matrix<float>& m) {
// ...
}
Matrix<float> convert(const Matrix<double>& m) {
// ...
}
float-> float和double-> double似乎不需要保留有意义的操作,因此实际上使编译器错误看起来是有益的(而模板机制实际上可能会成功,并且只会创建不必要的副本)。 / p>
在没有更完整的示例的情况下,首先需要对哑元参数感到困惑。
如果您设置了模板(例如,类型不只是这两个):
template <typename T2, typename T1>
Matrix<T2> convert(const Matrix<T1>& m) {
}
如果您试图在所有其他转换函数中编写一个单一的通用转换函数,则无法在C ++ 14之前简化所编写的内容(我的意思是还有其他方式可以编写它,但是似乎不太可能更简单)。
答案 1 :(得分:0)
一个选项可能是帮助程序类,这些类知道从Matrix到T到Matrix的转换类型,但是它们比decltype语句更漂亮,因为decltype语句对于代码而言是可读的并且是本地的。
矩阵可以从知道如何从T生成矩阵的基类派生吗?也许作为会员,您可以这样写:
class MatrixBase
{
public:
template <class T> class To
{ typedef Matrix<T> To; };
};
class Matrix<int>:public MatrixBase {
// ...
};
所有这些只是为了写:-> S::To<T>::To
正如您所说的,随着C ++ 14的革命,您可以进行全自动返回类型的事情。