假設我從這個使用 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類有一個方法foo。但是假設我想將該方法設為私有foo,并DoFoo從. 所以我嘗試添加一個朋友宣告:FooThingFooThing
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&);
在上課之前,編譯錯誤就消失了,但我得到一個鏈接錯誤,說DoFoo(FooThing&)或者DoFoo<FooThing>(FooThing&)是一個未定義的符號。
uj5u.com熱心網友回復:
是的!這個朋友宣告編譯和鏈接:
class FooThing
{
//public:
void foo() {}
template<HasFoo T>
friend void DoFoo(T&);
};
我將不得不四處尋找確切的標準,但我知道有一條規則,參考同一模板的多個宣告必須具有相同的約束(typename T此處不允許)。
uj5u.com熱心網友回復:
問題是您的概念檢查要求它必須T是一個完整的型別(因為使用了t.foo()),但是在朋友宣告時,該類FooThing是不完整的,因此該概念是無效的。您可以通過在朋友宣告中使用其他一些完整型別來確認這一點,并且該概念將按照您的預期作業。演示
有什么方法可以在保持概念的同時修復錯誤?
只要您的檢查需要T是一個完整的型別,這個涉及的友元宣告FooThing就不能作業,因為在友元宣告時,該類尚未完成。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/489102.html
上一篇:模板類作為函式引數[C ]
下一篇:沒有輔助型別的依賴型別
