C++ 变体和不完整类型:它是如何工作的?

C++ 变体和不完整类型:它是如何工作的?,c++,variant,C++,Variant,我知道std::variant适用于不完整类型。然而,我不明白它是如何工作的,因为在我的理解中,std::variant必须需要它所持有的类型的最大大小 那么,为什么这段代码不使用s1和s2编译呢。如何使它像std::variant那样工作 #include <variant> #include <vector> #include <type_traits> #include <typeinfo> #include <iostream>

我知道
std::variant
适用于不完整类型。然而,我不明白它是如何工作的,因为在我的理解中,
std::variant
必须需要它所持有的类型的最大大小

那么,为什么这段代码不使用
s1
s2
编译呢。如何使它像
std::variant
那样工作

#include <variant>
#include <vector>
#include <type_traits>
#include <typeinfo>
#include <iostream>

struct Rect;
struct Circle;

using Shape = std::variant<Rect, Circle>;

template<typename C>
struct S {static constexpr auto s = sizeof(C);};

constexpr auto s1 = S<Rect>::s;
constexpr auto s2 = sizeof(Rect);

struct Circle{};
struct Rect{
    std::vector<Shape> shapes;
};

int main() {}
#包括
#包括
#包括
#包括
#包括
struct Rect;
结构圆;
使用Shape=std::variant;
模板
结构S{static constexpr auto S=sizeof(C);};
constexpr auto s1=S::S;
constexpr auto s2=sizeof(Rect);
结构圆{};
结构矩形{
向量形状;
};
int main(){}
我知道std::variant适用于不完整类型

我想你不会的。没有

然而,我不明白它是如何工作的,因为

这是有道理的。它不能工作,因为:

在我的unstanding中,std::variant必须需要它所持有类型的最大大小


这是标准所说的:

[关于职能的决议]

在某些情况下(替换函数、处理函数、用于实例化标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件。 如果这些组件不满足其要求,本文档对实现不作任何要求

特别是,在以下情况下,效应未定义:

  • 如果在实例化模板组件或评估概念时使用不完整的类型([basic.types])作为模板参数,除非该组件特别允许

[variant]部分中没有允许不完整类型的特定规则。

AFAIK在
std::variant
中使用不完整类型是未定义的行为。好的,它编译后工作正常,但它是UB。谢谢:)。