首页 > 解决方案 > 处理 std::variant 中的循环依赖

问题描述

我正在尝试在以下情况下处理循环依赖:

我有一个 std::variant,说:

//types.h
using Types = std::variant<int, double, std::string, SomeClass>;

SomeClass 是一个非常简单的东西,它包含一些指针,带有一些模板逻辑:

#someclass.h
class SomeClass {
    // few simple members (pointers and an integer)
    
    void use(Types arg); // note usage of Types here

    template<typename T, typename Ts...> // implicitly assuming T == Ts... == Types
    void use(T arg, Ts... tail) {
        use(arg);
        use(tail...);
    }

    SomeClass(const SomeClass&) = default; // works fine
};

通常我会在“使用类型...”之前前向声明 SomeClass,但对于 std::variant 则无法做到。我也没有真正找到一种方法来前向声明“使用”指令。

我发现的一种方法是前向声明 SomeClass 并在 Types 中使用指向它的指针,但我不喜欢这个想法(SomeClass 是一个非常轻的对象,生命周期很短,我想让它远离堆)。

C++ 中有没有其他方法(除了指针)来解决这个问题?我的想法不多了。

谢谢 :)

编辑:

仅当我在真正定义 SomeClass 之前尝试使用 Types 时才会出现此问题,请参阅https://godbolt.org/z/4jzhEd

标签: c++c++17circular-dependencyvariant

解决方案


您提供的实时示例中,您需要解决的问题是SomeStruct在之后定义SomeClass

这样,您的变体在定义Types时将不再有任何不完整的类型。SomeStruct换句话说,这里是顺序:

class SomeClass;

using Types = std::variant<..., SomeClass>;

class SomeClass {
   // ... // Types used here, but doesn't need to have all complete types
};

struct SomeStruct {
    Types value;
    // ...
};

请参阅此处以获取实时示例。


推荐阅读