簡體   English   中英

Class type undefined in static member lambda function in C++17

[英]Class type undefined in static member lambda function in C++17

不久前,我試圖實現自己的 v-tables(用於教育目的)。 為此,我使用了 function 指針和 lambda。 在這樣做的過程中,我偶然發現了一個問題。 我沒有發布整個 v-table 代碼,而是編寫了一個 Minimal Reproducible Example。

由於某種原因,它無法編譯(C2027 - 使用未定義類型測試):

class Test
{
    int n;
    static inline auto f = [](Test* t)
    {
        return t->n;
    };
};

即使我像這樣前向聲明Testclass Test; .

我很好奇是什么導致了這種行為,因為int nclass Test都是在 lambda 之前聲明的。

我正在使用帶有 C++17 的最新 Visual Studio 2019。

Testlambda之前聲明,但未定義 class 定義僅在 class 本身的末尾完成,當您執行}; . 在那之前,它是一個不完整的類型。

而且您不能訪問不完整類型的成員。 或者至少,不是通過 object 實例,就像您在 lambda 中所做的那樣(此時您可以談論Test::n ,但您不能參加Test*並對其執行->n操作)。

現在,您可能會說,如果您創建了一個普通的f成員,您可以輕松地將 class 的定義放在那里並且它會起作用。 這是因為 C++ 對 class 的成員函數的定義有一個特殊規則。 即,這些函數的主體被認為是被定義為就好像它們被放置在 class 定義之后一樣。 因此,他們可以在內部使用 class,就好像它是一個完整類型一樣,因為這些 function 主體將在它們是完整類型的地方定義。

您的 lambda 不是 function 的成員; 這是一個 lambda function 被分配給一個類靜態變量。 static 變量的初始化程序沒有得到這種特殊處理,因此在 lambda 的 function 主體內部, Test被認為是不完整的。

您不能這樣做,因為 class 在 lambda 表達式的點上還不是一個完整的類型。

[類.mem]

6 class 的完整類上下文是

  • function 主體([dcl.fct.def.general]),

  • 默認參數,

  • noexcept 說明符,或

  • 默認成員初始化器

在 class 的成員規范內。 [ Note: A complete-class context of a nested class is also a complete-class context of any enclosing class, if the nested class is defined within the member-specification of the enclosing class. ——尾注]

7 A class 在類說明符的結束處被視為完全定義的 object 類型([basic.types])(或完整類型)。 class 在其完整類上下文中被認為是完整的; 否則,它在其自己的 class 成員規范中被視為不完整。

暫無
暫無

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

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