簡體   English   中英

C++ 中的前向聲明模板變量

[英]Forward-declaring template variable in C++

前向聲明模板變量會導致 ld 錯誤。

#include <iostream>
template<class T> extern int a;
template<class T> int a = 1;
int main()
{
    std::cout << a<int> << a<float>;
    return 0;
}
$ LANG=C g++ main.cpp -o main
/usr/bin/ld: /tmp/cccOb25F.o: in function `main':
main.cpp:(.text+0x6): undefined reference to `a<int>'
/usr/bin/ld: main.cpp:(.text+0x1d): undefined reference to `a<float>'
collect2: error: ld returned 1 exit status

但是,前向聲明變量(無模板)和前向聲明模板 function 工作正常。

#include <iostream>
extern int a;
int a = 1;
template<class T> int b();
template<class T> int b()
{
    return 2;
}
int main()
{
    std::cout << a << b<int>();
    return 0;
}

那么,是否可以使 C++ 中的前向聲明模板變量有效?

編輯

由於clang++工作正常,也許我不小心發現了g++的錯誤?

編輯2

我發現了大約 2.5 年前的錯誤報告(這里),這是完全相同的問題。 哦,我們需要一個可以閱讀 gcc 源代碼並修復它的人......

打開 GCC 錯誤報告 83342 -“帶有稍后定義的外部標記變量模板發出錯誤”

這是GCC 錯誤 83342 ,尚未解決。

GCC 似乎做出了這樣的假設,無論是否有意,在給定的翻譯單元 (TU) 中首先使用extern關鍵字聲明的變量模板必須在另一個TU 中定義(因此甚至不需要在同一個 TU 中查找它)。 例如 Clang 不做這個假設(並在同一個 TU 中找到定義和重新聲明)。

template<class T> extern int a;      // extern declaration.
template<class T>        int a = 1;  // definition.
template int a<int>;  // explicit instantiation definition for a<int> specialization.

// Clang: OK
// GCC:
// - error: explicit instantiation of 'a<int>' but no definition available

int main() {}

標准中沒有條款允許 GCC 做出上述假設,並且打開的錯誤報告是有效的。

我們可能會注意到 GCC 接受 function 模板的類似且可能更常見的情況:

template<class T> extern void f();    // extern declaration.
template<class T>        void f() {}  // definition.
template void f<int>();  // explicit instantiation definition for f<int>() specialization.

// Clang: OK
// GCC:   OK

int main() {}

暫無
暫無

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

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