删除转换操作符
Deleting conversion operators
是否有禁用转换操作符的方法?将它们标记为"= delete"会使其他事情变得混乱。
考虑以下代码:
class Foo
{
public:
Foo() :mValue(0) {}
~Foo() = default;
Foo(int64_t v) { mValue = v; }
Foo(const Foo& src) = default;
bool operator==(const Foo& rhs) { return mValue == rhs.mValue; }
/* after commenting these lines the code will compile */
operator int() const = delete;
operator int64_t() const = delete;
private:
int64_t mValue;
};
int main()
{
Foo foo1(5);
Foo foo2(10);
bool b1 = (foo1 == foo2);
bool b2 = (foo1 == 5);
}
无法编译,因为gcc抱怨==操作符有歧义:
test.cc: In function ‘int main()’:
test.cc:25:21: error: ambiguous overload for ‘operator==’ (operand types are ‘Foo’ and ‘int’)
bool b2 = (foo1 == 5);
^
test.cc:25:21: note: candidates are:
test.cc:25:21: note: operator==(int, int) <built-in>
test.cc:25:21: note: operator==(int64_t {aka long int}, int) <built-in>
test.cc:10:10: note: bool Foo::operator==(const Foo&)
bool operator==(const Foo& rhs) { return mValue == rhs.mValue; }
^
但是,在注释了转换操作符之后,代码将可以很好地编译和运行。
第一个问题是:为什么删除的转换操作符会给==操作符造成歧义?我认为它们应该禁用隐式Foo -> int转换,但它们似乎影响了int -> Foo转换,这对我来说听起来不合乎逻辑。
第二个问题:是否有一种方法来标记已删除的转换操作符?是的,通过不声明它们-但我正在寻找一种方法,将来任何人都可以看到这些转换是被设计禁用的。
任何对已删除函数的使用都是错误的(程序不会这样做)编译)。
如果函数被重载,首先进行重载解析;如果删除的函数是错误的,那么程序就是错误的选中。
在你的情况下,程序不能选择转换,因为你有3个变量
-
int→Foo
-
Foo→int
-
Foo→int64
第二个问题:您可以保持原样,但始终对int
使用显式转换。bool b2 = (foo1 == Foo(5));
我认为这是问题的关键:
[dcl.fct.def.delete]:
一个程序隐式或显式地引用一个被删除的函数,而不是声明它,是病态的。
…被删除的函数隐式地是内联函数([dcl.inline])。
[class.member.lookup/4]:
如果C包含名称f的声明,则声明集包含C中声明的满足的f的所有声明查找所使用的语言结构的要求。
即使你delete
函数,你仍然声明它。声明的函数将参与重载解析。只有当它是已解析的重载时,编译器才会检查它是否被删除。
在你的例子中,当这些函数声明出现时,有一个明显的歧义。
相关文章:
- 我可以将C 17 Capture lambda ConstexPR转换操作符的结果用作函数指针模板非类型参数吗?
- Clang vs GCC vs MSVC模板转换操作符-哪个编译器是正确的
- 为什么操作符的新函数需要强制转换
- c++中从整数到字符串的转换中,左移操作符是做什么的?
- 模板类型转换操作符=
- 链接隐式转换操作符
- 强制转换操作符函数在g++中可以很好地编译,但在其他编译器中不行.为什么
- 当目标类有多个构造函数时,消除强制转换操作符的歧义
- 删除转换操作符
- 强制转换操作符重载和引用
- 实现没有临时的转换操作符
- 不同的强制转换操作符被不同的编译器调用
- 将操作符转换为模板实参的特化
- 为什么模板化的用户定义转换操作符能够确定其返回类型?
- const转换操作符
- 在可强制转换为另一个模板类型的类模板中重载赋值操作符
- 调用转换操作符不能用于静态const变量
- 内部编译器错误-开关表达式中的模板化转换操作符
- 强制转换操作符可以是显式的吗?
- 在返回语句中统一初始化,并显式将操作符转换为bool