我试图根据预编译器变量获得类似模板转发的功能。但是,我遇到了奇怪的编译错误,所以我试着举例说明我正在做的事情。
我有一个矩阵类,它接受两个模板参数,它使用模板参数的方式基于预编译器变量,该变量确定我们是在列主要环境还是行主要环境中。
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文件中”的问题,标题和包含文件捆绑在同一个包中,因此保证定义与类定义。
答案 0 :(得分:1)
可能是this MSVC bug的另一种表现形式,虽然它有一个嵌套类型,而在这里你只是使用一个成员常量。
使用尾随返回类型来解决它 - 它也更短:
auto Matrix<rows, columns>::GetVector(size_t index) const
-> Vector<Matrix::vectorLength> {
//...
}
另外,如果你在两个地方都这样做,你可以写vectorLength
而不是Matrix::vectorLength
。