gpt4 book ai didi

c++ - 隐式转换未按预期工作

转载 作者:搜寻专家 更新时间:2023-10-31 01:30:42 25 4
gpt4 key购买 nike

我写了一个简单的Flags类,但我的运算符定义存在问题。似乎我依赖于一些不存在的隐式转换规则。

enum class SomeEnum { ONE, TWO, THREE };

template<typename Enum>
class Flags {
Flags(const Flags& f) { };
Flags(Enum e) { };

Flags& operator |=(Flags<Enum> f) {
//...;
return *this;
}
};

template<typename Enum>
Flags<Enum> operator |(Enum a, Flags<Enum> b) { return b | a; }

template<typename Enum>
Flags<Enum> operator |(Flags<Enum> a, Enum b) { return a |= b; }

int main() {
Flags<SomeEnum> flags = SomeEnum::ONE | SomeEnum::TWO;
return 0;
}

编译时出现这个错误:

implicit.cpp: In function ‘int main()’:  
implicit.cpp:26:40: error: no match for ‘operator|’ (operand types are ‘SomeEnum’ and ‘SomeEnum’)
Flags<SomeEnum> flags = SomeEnum::ONE | SomeEnum::TWO;

我的理解是,SomeEnum 中的一个s 被隐式转换为 Flags<Enum> ,然后传递给正确的运算符(operator)。我缺少什么规则?

编辑:

我看过https://stackoverflow.com/questions/9787593 ,但建议的解决方案(非成员(member)好友运营商)并没有解决我的问题。我确实删除了全局定义并添加了这些成员:

friend Flags operator |(Enum a, Flags b) { return b | a; }
friend Flags operator |(Flags a, Enum b) { return a |= b; }

但错误仍然相同(live demo)。

最佳答案

为了知道SomeEnum可转换为 Flags<SomeEnum>它已经必须推断出 Enum模板参数为 SomeEnum , 但它不能从参数中推断出这一点,因为它们都不匹配 Flags<Enum> .

即必须在检查到另一种类型的转换之前进行模板参数推导。

您可以调整函数,使只有一个参数参与参数推导:

template<typename T> struct nondeduced { using type = T; }

template<typename Enum>
Flags<Enum> operator |(Enum a, Flags<typename nondeduced<Enum>::type> b)

或等同于:

template<typename E> struct FlagType { using type = Flags<E>; }

template<typename Enum>
Flags<Enum> operator |(Enum a, typename FlagType<Enum>::type b);

这使用了 Enum非推导上下文中的模板参数,因此只有另一个参数用于推导。

但是在这样做之后你现在有不明确的重载,因为编译器无法知道你是想转换第一个参数还是第二个参数。

您需要添加一个需要两个 SomeEnum 的重载类型,并执行转换为 Flags<SomeEnum>明确地。如果枚举类型应该与 operator| 一起使用那么它应该自己定义该运算符。

另一个不涉及更改枚举类型的选项是添加一个帮助程序,将枚举器转换为 Flags。对象:

template<typename Enum>
inline Flags<Enum> flags(Enum e) { return Flags<Enum>(e); }

然后你可以说SomeEnum::TWO | flags(SomeEnum::TWO)这避免了歧义。

作为风格点,don't use ALL_CAPS for enumerators .

关于c++ - 隐式转换未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47230960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com