[英]C++20 concepts: How do I use concepts to check if an object can use shared_from_this()?
[英]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.