std :: optional的模糊运算符重载?

时间:2017-03-21 13:06:02

标签: c++ gcc operator-overloading optional c++17

考虑this代码。

struct Test : public std::optional<int>  { };

Test o1, o2;
o1 == o2;

最后一行gcc-7.0.1抱怨error: ambiguous overload指向两个重载,用于将可选项与值进行比较。但它不应该只用两个选项选择重载并成功编译代码吗?

修改 对于价值比较而言,不应该超载吗?#34;警卫&#34;不允许他们实例化从std :: optional?

继承的类型

1 个答案:

答案 0 :(得分:4)

此表达式有三个重载:

// #1, with T=int, U=int
template <class T, class U> 
constexpr bool operator==(optional<T> const&, optional<U> const& );

// #2, with T=int, U=Test
template <class T, class U> 
constexpr bool operator==(optional<T> const&, U const& );

// #3, with T=int, U=Test
template <class T, class U> 
constexpr bool operator==(U const&, optional<T> const& );

#2#3的转化序列比#1更好,因为其中一个参数(U const&)是Test的完全匹配而不是#2派生到基础的转换。

虽然我们可以选择#3#1#2,但我没有理由更喜欢#3#2中的一个 - 每个都有一个参数中的转换序列更好,第二个参数中的转换序列更差。

因此,它含糊不清。请注意,#3int都是格式正确的运算符,因为您确实可以将TestU进行比较。要消除歧义,您必须另外添加optional<T>不从Test继承的约束,这是一个非常具体的约束。

您可以通过将一个或另一个optional<int>投放到optional==(Test, Test)或仅提供 it 'should have plane in the Airport' do plane = double(:plane, airborne: true) allow(plane).to receive(:land_plane) airport.land(plane) expect(airport.planes_in_airport).to include plane end 来解决此问题。