注意:我正在使用 gcc,但在 Godbolt.org 上進行了測驗,它也適用于 msvc,但不適用于 clang
我偶然發現以下簡單函式在模板化類中編譯,但不是作為自由函式編譯。有人可以解釋為什么嗎?
編譯正常:
template <typename T = void>
class A
{
public:
static constexpr std::string f()
{
return std::string();
}
}
不編譯:
constexpr std::string f()
{
return std::string();
}
拋出錯誤:
error: invalid return type ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} of ‘constexpr’ function ...
...
/usr/include/c /9/bits/basic_string.h:77:11: note: ‘std::__cxx11::basic_string<char>’ is not literal because:
77 | class basic_string
| ^~~~~~~~~~~~
/usr/include/c /9/bits/basic_string.h:77:11: note: ‘std::__cxx11::basic_string<char>’ has a non-trivial destructor
uj5u.com熱心網友回復:
std::string應該是 C 20 中的文字型別。但是,GCC 似乎還沒有實作這個新特性,所以它不能接受std::string作為constexpr函式的回傳型別。
但是,當constexpr函式是模板的一部分時,它在實體化之前不會作為函式存在。類模板是類的藍圖;它本身不是一個類。當類模板實體,然后它的成員集合也就應運而生。因此,在您的第一個示例中,您擁有的是一個始終會產生格式錯誤的實體化的類模板,因為A<T>::f它將始終具有無效的回傳型別。發生這種情況時,程式“格式錯誤,不需要診斷”,這意味著程式格式錯誤,但不需要編譯器告訴您程式格式錯誤。如果編譯器接受該程式,則運行該程式的結果是未定義的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/326458.html
