繁体   English   中英

C ++:使用constexpr别名模板参数,导致函数定义与声明不匹配

[英]C++ : Using constexpr to alias template parameters, causing function definitions to not match to declarations

我试图获得类似基于预编译器变量的模板转发之类的东西。 但是,我遇到了奇怪的编译错误,因此我将尝试举例说明我的工作。

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

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预编译器语句,因此,我没有这样做,而是考虑一次“转发”模板参数,并引用这些模板参数。 例如 ...

#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
}

并且在包含文件中,该函数的定义如下:

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

当我去编译它时,我遇到了以下错误

错误C2244:“ Matrix :: GetVector”:无法将函数定义与现有声明匹配

当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文件中放置模板定义”的问题,标头和包含文件捆绑在同一个include包中,因此可以确保该定义与类定义一起存在。

此MSVC错误的另一种体现,尽管该类型具有嵌套类型,而在这里您只是使用成员常量。

使用尾随返回类型来变通-它也更短:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM