問題描述
我寫了這個 C++11 trait 模板來檢查一個類型是否完整:
I wrote this C++11 trait template to check whether a type is complete:
template <typename...>
using void_t = void;
template <typename T, typename = void>
struct is_complete : std::false_type
{};
template <typename T>
struct is_complete<T, void_t<decltype(sizeof(T))>> : std::true_type
{};
并像這樣測試:
struct Complete {};
int main()
{
std::cout << is_complete<Complete>::value
<< is_complete<class Incomplete>::value
<< '
';
}
我希望測試程序打印10
,這就是我用clang 3.4 編譯它時得到的輸出.但是,當使用 gcc 4.9 編譯時,它會打印 11
—— 錯誤地將 class Incomplete
識別為完整.
I expected the test program to print 10
, and that is the output I get when I compile it with clang 3.4. However, when compiled with gcc 4.9, it prints 11
instead -- mistakenly identifying class Incomplete
as complete.
我不確定我的代碼是否正確,但在我看來,即使它是錯誤的,它在兩個編譯器上的行為也應該相同.
I don't know for sure if my code is correct, but it seems to me that even if it's wrong, it should behave the same on both compilers.
問題 1:我的代碼正確嗎?
問題 2:我是否在其中一個編譯器中發現了錯誤?
Question 1: Is my code correct?
Question 2: Have I found a bug in one of the compilers?
我不是要求替換我的代碼.我在問 gcc 或 clang 中是否存在錯誤,以及這個特定的構造是否正確.
I'm not asking for a replacement for my code. I'm asking whether there is a bug in gcc or clang, and whether or not this particular construct is correct.
推薦答案
問題似乎出在 void_t
的定義上.定義為
The problem appears to be with the definition of void_t
. Defining it as
template<typename... Ts>
struct make_void { typedef void type;};
template<typename... Ts>
using void_t = typename make_void<Ts...>::type;
而是在兩個編譯器上產生正確的結果(10
)(Demo).
instead yields the correct result (10
) on both compilers (Demo).
我相信這與 N3911,論文提出了 void_t
和 CWG 問題 1558.本質上,該標準不清楚別名模板特化中未使用的參數是否會導致替換失敗或被簡單地忽略.委員會 2014 年 11 月會議通過的 CWG 問題決議闡明了問題中 void_t
的較短定義應該有效,并且 GCC 5.0 實施了該決議.
I believe this is the same issue noted in section 2.3 of N3911, the paper proposing void_t
, and CWG issue 1558. Essentially, the standard was unclear whether unused arguments in alias template specializations could result in substitution failure or are simply ignored. The resolution of the CWG issue, adopted at the Committee's November 2014 meeting, clarifies that the shorter definition of void_t
in the question should work, and GCC 5.0 implements the resolution.
這篇關于我對 is_complete 類型特征的實現是否暴露了編譯器錯誤?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!