簡體   English   中英

如何修復涉及概念和朋友的 C++20 編譯錯誤?

[英]How can I fix a C++20 compile error involving concepts and friends?

假設我從這個使用 C++20“概念”的簡單示例開始:

template <typename T>
concept HasFoo = requires( T t )
{
    t.foo();
};

template <HasFoo T>
void DoFoo( T& thing )
{
    thing.foo();
}

class FooThing
{
public:
    void    foo() {}
};

int main(int argc, const char * argv[]) {
    FooThing x;
    DoFoo( x );
    
    return 0;
}

這編譯,並且概念驗證FooThing class 有一個方法foo 但是假設我想將方法foo設為私有,並從FooThing的另一種方法在FooThing DoFoo 所以我嘗試添加一個朋友聲明:

class FooThing
{
private:
    void    foo() {}
    
    friend void DoFoo<FooThing>( FooThing& thing );
};

這會導致錯誤消息: FooThing不滿足HasFoo因為t.foo()無效:成員訪問不完整類型FooThing

為了讓自己確信這個概念對於這個問題真的很重要,我試着沒有它,

template <typename T>
void DoFoo( T& thing )
{
    thing.foo();
}

然后錯誤消失了。 有沒有辦法在保持概念的同時修復錯誤?


如果我嘗試嘗試回答的建議並添加前向聲明

template<typename T> void DoFoo(T&);

在 class 之前,編譯錯誤消失了,但我收到一個鏈接錯誤,指出DoFoo(FooThing&)DoFoo<FooThing>(FooThing&)是未定義的符號。

是的! 這個朋友聲明編譯和鏈接

class FooThing
{
//public:
    void    foo() {}    

    template<HasFoo T>
    friend void DoFoo(T&);
};

我將不得不四處尋找確切的標准,但我知道有一條規則,即引用同一模板的多個聲明必須具有相同的約束(此處不允許使用typename T )。

問題是你的概念檢查要求T需要是一個完整的類型(因為使用了t.foo() )但是在朋友聲明的時候 class FooThing不完整的,所以這個概念是無效的。 您可以通過在朋友聲明中使用其他一些完整類型來確認這一點,並且該概念將按您的預期工作。 演示

有沒有辦法在保持概念的同時修復錯誤?

只要你的檢查要求T是一個完整的類型,這個涉及FooThing的朋友聲明就不能工作,因為在朋友聲明 class 尚未完成時。

暫無
暫無

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

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