簡體   English   中英

可以在 C++ 中實例化和/或專門化遞歸/自引用模板(使用指針)嗎?

[英]Can a recursive/self-referential template (using pointers) be instantiated and/or specialized in C++?

我想從 STL 實例化一個模板,使用地圖、矢量和 arrays,如下所示:

map<some_type,vector<map<some_type,vector...>*>> 元素;

省略號只是表示無限遞歸定義的偽代碼,當然不可能打出來。 基本上,向量應該只包含指向其他映射的指針,這些映射在結構/定義上與包含向量的 map 相同。 我知道有使用類和結構的解決方法,問題是是否可以只使用模板。 我希望我能以某種方式將整個外部 map 定義為某種“模板變量”或其他占位符,例如“T”,然后編寫以下內容:

map<some_type,vector<T*>> 元素;

我將單獨定義 T 為引用整個 map。但是由於遞歸,這樣的變量 T 將根據自身定義,即本身為 T 的子組件。稍后我會在運行時根據需要分配更多映射在堆上並將指向它們的指針插入向量中,這樣我就可以遞歸地(不確定地經常)遍歷向量中的 map,這樣我就可以在堆上實例化更多映射,再次將指向它們的指針保存在其中向量。

有沒有一種(優雅的)方法來做到這一點(如果有的話)?

通過抽象出遞歸變量,您走在了正確的軌道上:

template <typename Self>
using F = std::map<int, std::vector<Self*>>;

問題是找到滿足T == F<T>的類型T 這被稱為尋找固定點 在這些術語中,我們想要一個模板Fix采用模板模板參數,例如Fix<F> == F<Fix<F>>

抽象地,在惰性函數式語言中, Fix<F> = F<Fix<F>>可以作為Fix<F>的定義。 這巧合地告訴我們 C++ 中發生故障的確切原因。在 C++ 符號中,這個假設定義如下所示:

template <template<typename> typename F>
using Fix = F<Fix<F>>; // does not compile

這從根本上取決於惰性,但模板本質上是惰性的,所以這不是問題。 真正的問題是名稱查找。 我們不能在 C++ 的右側引用Fix 。這是一個有點人為的限制,但這是我們的語言。

我看不出解決這個問題的方法,所以我無法避免引入一個通用的輔助結構:

template <template<typename> typename F>
struct Fix : F<Fix<F>> { };

雖然別名不能在定義中引用它們自己的名稱,但類和結構可以。

解決所有這些問題后,我們就有了解決方案:

// Our type
using Type = Fix<F>;

// It instantiates
auto map = Type{};

// The inner type is the same as the outer type
using inner_type = std::decay_t<decltype(*std::declval<Type::mapped_type::value_type>())>;
static_assert(std::is_same_v<Type, inner_type>);

// We can push_back the address of ourself
map[0].push_back(&map);

在 godbolt 上看到這個。

暫無
暫無

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

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