簡體   English   中英

遞歸定義的前向聲明使用指令

[英]Forward declare using directive for recursive definitions

我有一個包含變體類型項目的數組,我想使用通用 std::array 迭代器對其進行迭代。 現在我想用我自己的 class array2來管理陣列。 但是,該變體也可能包含一個類型為array2的 object,它是使用變體本身實例化的,這意味着 val 已經作為模板參數需要。

從邏輯的角度來看,這個問題似乎是可以解決的:我沒有在array2中使用val類型的數據成員,這意味着 memory 的 val 布局可以在定義時固定。 但是,我必須轉發聲明 val 類型才能在 val 的定義中使用它。 我能以某種方式做到這一點嗎? 或者有沒有更慣用的方法來解決這個問題/解決方法?

我已經檢查了C++ 前向聲明使用指令,但它沒有回答我的問題,因為它不使用遞歸(這使它更容易)。

編譯器瀏覽器

#include <variant>
#include <cstddef>
#include <array>


template <typename T, size_t V> struct array2;

template <size_t V>
using val = std::variant<std::monostate, int, array2<val, V>>;

template <typename T, size_t V>
struct array2
{
    using iterator = typename std::array<T, V>::iterator;

    iterator begin_; // array allocation not done in here
    iterator end_;
};

int main() {}

產量:

<source>:9:54: error: 'val' was not declared in this scope
    9 | using val = std::variant<std::monostate, int, array2<val, V>>;

更新

請注意, array2的大小不取決於 val 的定義,除了using聲明確實要求std::array<val, V>顯然是完整的。

不,你想要的是不可能的。

cppreference說關於類型別名的using

type-id [目標類型] 不能直接或間接引用標識符[正在定義的類型]。

在某些情況下問題是否“邏輯上”可解決並不重要,因為 C++ 是靜態類型語言,所有類型都必須在編譯時知道,而遞歸類型根本不可能,因為它們的類型解析過程永遠不會結尾。

前向聲明是完全不同的:使用前向聲明,您只是給出沒有定義的類型聲明,但該類型本身沒有問題,linker 將負責查找定義。 有關前向聲明的更多信息,請參閱此答案

您需要像這樣簡單地擺脫遞歸,從 val 中獲取array2<val, V> val 你可以使用這樣的東西來達到同樣的效果:

using val = std::variant<std::monostate, int>;

template <size_t V>
using valOrArray2Val = std::variant<val, array2<val, V>>;

我找到了解決方案。 如果您 typedef 一個 class 類型,您可以簡單地創建一個繼承 class 的代理類型,並受益於模板實例化僅在代理聲明已經完成時完成的事實:

現場演示

#include <variant>
#include <cstddef>
#include <array>


template <typename T, size_t V> struct proxy;

template <typename T, size_t V>
struct proxy : std::variant<std::monostate, int, proxy<T, V>>
{
    using iterator = typename std::array<T, V>::iterator;

    iterator begin_; // array allocation not done in here
    iterator end_;
};

int main() {}

注意:這僅在代理 class 中沒有代理數據成員時才有效(但這在這種情況下很明顯)。

暫無
暫無

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

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