簡體   English   中英

鍵入別名和不完整類型

[英]Type aliases and incomplete types

我可能已經到達這里解決什么應該是一個簡單的問題。 我在這里開始這個問題: 在編譯時獲取基類類型

基本上我正在嘗試讓類管理它自己的指針類型。 我正在包裝一個C庫,其中一些結構嵌入了引用計數,而其他結構則沒有。 那些沒有的,我想使用shared_ptr。 那些做的,我想使用intrusive_ptr。 我想避免依賴程序員的智力來確保使用正確的包裝器。 最后,我想添加更多依賴於此行為的功能,但我還沒有。

@Yakk使用模板類型別名提出了一個有趣的解決方案,我試圖實現它。 不幸的是,我已經把自己放在了一個我似乎無法解決循環引用編譯器滿意度的地方。 我得到一個“嵌套名稱說明符中命名的不完整類型'Test2'”指向“using pointer =”行的錯誤。 對於我對Test :: f()的定義,我也得到了一個奇怪的“定義與返回類型的聲明不同”,但我懷疑一旦我解決了第一個錯誤,它可能會自行解決。

我在這個錯誤類型上找到的大多數引用涉及頭文件的排序,但即使一個文件中的所有內容我都無法弄清楚如何訂購以使這個問題消失。

有任何想法嗎?

#include <iostream>
#include <memory>


template<typename T>
class Pointered: public std::enable_shared_from_this<T>
{
public:
    using pointer=std::shared_ptr<T>;     //<-- incomplete type named error
    using weakPointer = std::weak_ptr<T>;
};


template<typename T>
using Ptr =  typename T:: pointer;

template<typename T>
using WkPtr = typename T:: weakPointer;


class Test2;

class Test:public Pointered<Test>
{
public:
    Ptr<Test2> f();
};


class Test2:public Pointered<Test2>
{
public:
    Ptr<Test> p;
    Test2(Ptr<Test> ptr):p(ptr){}
};


int main(int argc, const char * argv[])
{
    Ptr<Test> p=std::make_shared<Test>();
    Ptr<Test> p3=p;
    p->f();
    std::cout << "Refcount: " << p.use_count() << std::endl;
}


//definition differs from declaration in return type error here
Ptr<Test2> Test::f()
{
    return Ptr<Test2>(new Test2((Ptr<Test>)shared_from_this()));
}

您無法轉發聲明嵌套類型,因為您需要定義封閉類型,但在您的情況下,您有一個循環依賴關系來禁止它。

首先要考慮的是循環依賴是否真的是一個好主意。 在大多數情況下,循環依賴性被認為是代碼氣味(表明設計存在問題)。 如果你可以刪除循環依賴,那么一切都會變得更容易。

另一種替代方法是將對嵌套類型的依賴性移動到類型特征,可以在外部和類型定義之前定義:

template <typename T>
struct pointer_traits;

template <>
struct pointer_traits<Test1> {
   typedef std::shared_ptr<Test1> ptr;
   typedef std::shared_ptr<Test1> wptr;
};

通過將依賴項移到實際類型之外,您不再具有循環依賴性(在語法級別,您仍應重新訪問設計)。 然后,您可以根據需要添加語法糖:

template <typename T>
using ptr = typename pointer_traits<T>::ptr;

class Test1 {
    ptr<Test2> p2;
};

如果你真的希望這些類型也是嵌套的,你可以使用繼承將它們帶入范圍,或者以更簡單的方式添加相應的typedef:

class Test1 {
    typedef ptr<Test1> ptr_t;
// ...

請注意,這是一個粗略的估計,如果你選擇這種方法,你可以工作性狀的細節和類型有點使它更甜通過增加更多的語法糖,例如,您可以提供兩個特點shared_ptr_traitsintrusive_ptr_traits並提供單行特征來確定從哪個中提取typedef,將特征(每種類型)的定義減少到一行。

暫無
暫無

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

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