C ++:使用constexpr为模板参数设置别名,导致函数定义与声明

时间:2016-01-01 06:05:14

标签: c++ templates compiler-errors visual-studio-2015 constexpr

我试图根据预编译器变量获得类似模板转发的功能。但是,我遇到了奇怪的编译错误,所以我试着举例说明我正在做的事情。

我有一个矩阵类,它接受两个模板参数,它使用模板参数的方式基于预编译器变量,该变量确定我们是在列主要环境还是行主要环境中。

template<size_t vectorLength>
class Vector {
//... Implementation stuff
}

#define ROW_MAJOR

template<size_t rows, size_t columns>
class Matrix {

#if defined(ROW_MAJOR)
std::array<Vector<columns>, rows> m_vectorArray;
#else
std::array<Vector<rows>, columns> m_vectorArray;
#endif

//... Other stuff
}

正如您可能想象的那样,这导致我的代码中到处都有很多#if#else预编译语句,所以我没有这样做,而是考虑&#34;转发&# 34;一个点中的模板参数,并参考那些模板参数。例如......

#define ROW_MAJOR

template<size_t rows, size_t columns>
class Matrix {

#if defined(ROW_MAJOR)
static constexpr size_t numberOfVectors = rows;
static constexpr size_t vectorLength = columns;
#else
static constexpr size_t numberOfVectors = columns;
static constexpr size_t vectorLength = rows;
#endif

std::array<Vector<vectorLength>, numberOfVectors> m_vectorArray
//... Other stuff
}

这很有效,直到我不得不返回单个向量。我试图在Matrix中声明一个函数:

template<size_t rows, size_t columns>
class Matrix {

//...Insert stuff from above
Vector<Matrix::vectorLength> GetVector(size_t index) const;
// ... Other stuff
}

在include文件中,函数定义如下:

template<size_t rows, size_t columns>
Vector<Matrix<rows, columns>::vectorLength> Matrix<rows, columns>::GetVector(size_t index) const
{
//... Implementation
}

当我去编译它时,我有以下错误

  

错误C2244:&#39; Matrix :: GetVector&#39;:无法将函数定义与现有声明匹配

当Visual Studio报告此错误时,它会尝试通过打印定义签名和函数GetVector的所有声明签名来帮助我。

note: definition
note: 'Vector<Matrix<rows,columns>::vectorLength> Matrix<rows,columns>::GetVector(size_t index)'
note: existing declarations
note: 'Vector<Matrix<rows,columns>::vectorLength> Matrix<rows,columns>::GetVector(size_t index)'

两个匹配角色的角色(我知道这是一个例子,但我复制并粘贴了我在实际代码中得到的两个注释,比较它们,它们匹配字符对于角色来说,所以我想我的问题是......这是对constexpr的滥用吗?有什么我忘记写的吗?这是Visual Studio编译器中的一个错误(我已经遇到了许多已经处理constexpr的VS错误)。或者这是一个愚蠢的方式来解决这个问题?

一些注意事项:我尝试将定义放在头文件中,所有编译都很好。这不是“不要将模板定义放在cpp文件中”的问题,标题和包含文件捆绑在同一个包中,因此保证定义与类定义。

1 个答案:

答案 0 :(得分:1)

可能是this MSVC bug的另一种表现形式,虽然它有一个嵌套类型,而在这里你只是使用一个成员常量。

使用尾随返回类型来解决它 - 它也更短:

auto Matrix<rows, columns>::GetVector(size_t index) const
     -> Vector<Matrix::vectorLength> {
//...
}

另外,如果你在两个地方都这样做,你可以写vectorLength而不是Matrix::vectorLength