簡體   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