C++ 为什么不是';t std::variant是否允许与它的一种替代类型进行比较?

C++ 为什么不是';t std::variant是否允许与它的一种替代类型进行比较?,c++,c++17,std-variant,C++,C++17,Std Variant,例如,将std::variant与T1或T2进行等效比较应该非常有用。到目前为止,我们只能与相同的变体类型进行比较。一个变体可能有多个相同类型的副本。例如,std::variant std::variant的一个给定实例与另一个实例比较相等,当且仅当它们持有相同的变量备选方案且所述备选方案的值比较相等时 因此,一个std::variant和index()0与一个std::variant和index()1相比并不等于一个std::variant和index()1,尽管活动的变量备选方案具有相同的类

例如,将
std::variant
T1
T2
进行等效比较应该非常有用。到目前为止,我们只能与相同的变体类型进行比较。

一个变体可能有多个相同类型的副本。例如,
std::variant

std::variant
的一个给定实例与另一个实例比较相等,当且仅当它们持有相同的变量备选方案且所述备选方案的值比较相等时

因此,一个
std::variant
index()
0与一个
std::variant
index()
1相比并不等于一个
std::variant
index()
1,尽管活动的变量备选方案具有相同的类型和相同的值


因此,本标准未实施通用的“与
T
”比较。但是,您可以使用
标题中的其他辅助工具工具(例如
std::holds\u alternative
std::get
)自由设计自己的比较运算符重载。

这是标准委员会的任意决定

好吧,不是很武断。关键是你有一个比较严格的尺度,包括以下几点:

  • 最严格:只有变体可以彼此相等,并且它们需要在备选方案序列(即类型)、实际备选方案(实际上是索引,因为您可以有多个相同的类型备选方案)和值上都匹配
  • 不那么严格:变量替代品(作为一种类型)和值相等,但不是替代品序列相等,也不是该序列中的索引相等(因此相同类型的两个不同替代品中的相同值将相等)
  • 最宽松:活动备选方案中的值相等,如果相关,则隐式转换其中一个元素
这些都是有效的选择。C++委员会根据各种外在标准做出了决定。尝试查找
std::variant
提案,因为它可能说明了这些标准是什么

(*)-实际上是一个晶格。

我无法回答问题的“为什么”部分,但既然您认为能够将
std::variant
T1
T2
进行比较会很有用,那么这可能会有所帮助:

template<typename T, class... Types>
inline bool operator==(const T& t, const std::variant<Types...>& v) {
    const T* c = std::get_if<T>(&v);
    if(c)
        return *c == t;
    else
        return false;
}

template<typename T, class... Types>
inline bool operator==(const std::variant<Types...>& v, const T& t) {
    return t == v;
}
模板
内联布尔运算符==(常数T&T,常数std::变量和v){
const T*c=std::get_if(&v);
如果(c)
返回*c==t;
其他的
返回false;
}
模板
内联布尔运算符==(常量标准::变量和变量,常量T和T){
返回t==v;
}

这不是对问题的回答,只是对情况的陈述。您没有说明为什么“std::variant的给定实例与另一个实例比较相等,当且仅当等。等等。”当将
int
std::variant
进行比较时,它可以将活动成员与
int
@einpoklum进行比较。标准刚刚决定应该是这样。我正在解释为什么标准中没有对
T
进行一般比较的原因(根据比较运算符在标准中的工作方式)。@MaximEgorushkin您可能希望这样,但这不是标准决定的。@CruzJean,在另一种情况下,你现在无法区分这两种情况——这种比较也可能是不经意的。我不确定该标准考虑的是什么用例,但是,可以将一个整数封装到一个唯一的类中,并从中获得更多好处。我认为c++20刚刚将其添加到草稿中,并在同一链接中添加了@GuillaumeRacicot,我相信它是说int将被隐式转换为
std::variant
,以满足比较函数签名。对于int,这可能是微不足道的。但是对于一个字符串,这可能意味着一个副本。这个比较在C++17中不也应该工作吗?运算符==是一个独立函数。variant有一个非显式的转换构造函数,所以variant()==T1()应该将T1转换为variant,它应该找到独立的运算符==。事实上,经过一次检查,我发现它不起作用。为什么会这样?实际上下面的代码是有效的:struct X{template X(T&&){};布尔运算符==(X常数&,X常数&);X(10);布尔b=x==10;因此,它似乎与运算符==作为模板有关。