簡體   English   中英

C ++:為什么這個constexpr模板函數在VS2017中導致內部錯誤?(在gcc中可以)

[英]C++: Why does this constexpr template function cause an internal error in VS2017?(In gcc is ok)

此代碼在GCC中編譯良好,但它在Visual Studio 2017編譯器中導致內部錯誤。 我的代碼有什么問題? 或者它是編譯器問題? 我聽說VS不使用兩個階段名稱查找,這在某些情況下可能會導致問題。

template <typename T>
constexpr auto doSomeSum(const T* a, const T* b) {
    if (a > b)return 0;
    auto sum = 0;
    while (a != b)
        sum += *(a++);
    return sum;
}

int main()
{
    constexpr int arr[] = { 1,2,3,4,5,6,7,0b1000,9,10 };
    constexpr float second[] = { 1,2,3,4,5,6,7,8,9,10 };
    constexpr auto a = doSomeSum<int>(arr, arr+10);
    constexpr auto b = doSomeSum<float>(second,second+10); //works if I comment this line
    return 0;
}

問題(在MSVC 2015中也會發生)似乎是它將返回類型和sum的類型推導為int ,然后在T是不同類型時具有動脈瘤。 我不確定2017年,但2015年在內爆之前發出此警告:

main.cpp(6):警告C4244:'+ =':從'const float'轉換為'int',可能丟失數據
main.cpp(15):注意:參見函數模板實例化'int doSomeSum(const T *,const T *)'正在編譯

  [ T=float ] 

第6行是:

    sum += *(a++);

因此,它將*(a++)視為const float ,但將sum視為int ; 這是因為sum初始化為0 ,一個整數字面值。 但是,我們可以通過使用T{0}初始化它,將sum的類型綁定到模板參數來輕松解決此問題。 因為這將導致返回類型推斷以確定兩個沖突類型( int0Tsum ),我們還必須更改第一行以返回T{0} 因此,最終結果是:

template <typename T>
constexpr auto doSomeSum(const T* a, const T* b) {
    if (a > b)return T{0};
    auto sum = T{0};
    while (a != b)
        sum += *(a++);
    return sum;
}

使用Compiler ExplorerRiSE4Fun的MSVC 2015在線環境進行測試 (請注意,后者不提供鏈接到各個會話的任何工具)。 使用GCC和Clang測試原始代碼表明兩者都有相同的問題,Clang也因此而發出錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM