解决隐藏歧义的不明确用户定义转换
Resolving ambiguous user-defined-conversion where ambiguity is hidden
下面的代码为整数创建一个基类包装器。它提供了一个方法来获取和设置其值,以及一个用户定义的转换和一个赋值运算符,以方便使用。
派生类是一个模板(旨在与枚举一起使用),它继承了基类包装器,该包装器隐藏了基类的值(),用户定义的转换和赋值运算符,并将它们替换为专门与提供的模板参数(枚举)一起使用的版本。
class Base
{
public:
Base( int e ) : e_(e) {}
inline const int& value() const { return e_; }
inline void value( int e ) { e_ = e; }
inline operator const int& () const { return value(); }
inline Base& operator= ( int e ) { value( e ); return *this; }
protected:
int e_;
};
template< typename E >
class Enum : public Base
{
using Base::value;
using Base::operator const int&;
using Base::operator=;
public:
Enum( E e ) : Base( e ) {}
inline E value() const { return static_cast<E>( Base::value() ); }
inline void value( E e ) { Base::value( e ); }
inline operator E () const { return static_cast<E>( Base::value() ); }
inline Enum<E>& operator= ( E e ) { Base::value( e ); return *this; }
};
enum foo_t {
FOO_A,
FOO_B,
FOO_C
};
typedef Enum<foo_t> Foo;
现在让我们像这样调用这段代码:
Foo e( FOO_A );
e = FOO_B; // Ok!
foo_t b = e; // Ok!
// Why is this not ok?
if ( e ) {
printf("error C2451!");
}
if ( e.value() ) { // Ok!
e = FOO_C;
}
// Why is this not ok?
switch ( e ) {
default:
printf("error C2450!");
}
switch ( e.value() ) { // Ok!
default:
e = FOO_A;
}
为什么当我显式隐藏基类的用户定义转换时,if 和 switch 语句无法编译 ( Ambiguous user-defined-conversion
)(并且 if 和 switch 语句应该无法访问)。同样模棱两可的e.value()
函数不会受到此问题的影响。
1>test.cpp(60): error C2451: conditional expression of type 'Foo' is illegal
1> Ambiguous user-defined-conversion
1>test.cpp(69): error C2450: switch expression of type 'Foo' is illegal
1> Ambiguous user-defined-conversion
ref#1 和 ref#2 (我似乎找不到实际说这句话的标准,只有人们引用它......
看来C++标准对条件有这样的说法:
条件应为整型、枚举型或存在单个非显式转换为整型或枚举类型的类类型 (12.3)。如果条件是类类型,则通过调用该转换函数来转换条件,并且在本节的其余部分中使用转换结果代替原始条件。进行整体促销。
由于有 2 个用户定义的转换"可用",即使只有 1 个可以访问,标准也说这不行。
(这些using
语句在Enum
是什么? 我不知道他们是做什么的。
我不确定为什么会发生错误,但是您当然可以通过向Base
添加以下内容来解决if
语句的问题:
inline operator bool () const { return e_ != 0; }
至于switch
,我从未见过除了允许的整数类型之外的任何东西(Foo
不是),我怀疑编译器是否足够聪明,可以尝试自己找到强制转换为枚举运算符。 无论如何,我总是会在那里打电话给value()
。
相关文章:
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- Visual C++(VS2017)中用户定义的转换不明确
- 使用用户定义的参数调用future/async并调用类方法
- 带有用户定义类的c++折叠表达式
- g++用户定义的动态链接库上的全局new和delete运算符
- 直接在 unordered_map 的方法中使用哈希,而不是生成哈希的用户定义对象
- 修改"std::set"中用户定义类型的值
- 参数包构造函数在类模板中隐藏用户定义的转换
- MAKE:找不到包含的用户定义的头文件?
- C++:用户定义的显式类型转换函数错误
- 从用户定义的类生成格式字符串?
- 为用户定义的类正确调用复制构造函数/赋值运算符
- C++ 向量与用户定义的类比较?(==, <, >)
- STL 用户定义的二进制操作
- 将用户定义的类型与 std::vector 和 std::sort 一起使用
- 为什么用户定义的函数不按照给定的顺序对相同长度的元素进行排序?
- 使用宏编译时使用用户定义的数学函数,或者仅使用 c++ 中标准数学库中的函数
- C++:用户定义的类,以成员字段作为地址