模板函数的返回类型未知,使用decltype时代码重复

时间:2019-04-01 11:04:59

标签: c++ c++11

在我的工作中,有几种模板数学类(例如矩阵)。

可以使用浮点数或双精度数(或其他数值类型,但就此而言,并不重要)来实现对象。

一个双重对象只能与另一个双重对象进行交互。为此,功能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()杂物,我认为问题尚未解决。

2 个答案:

答案 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的革命,您可以进行全自动返回类型的事情。