为啥不使用强制转换语法调用“operator void”?
Posted
技术标签:
【中文标题】为啥不使用强制转换语法调用“operator void”?【英文标题】:Why is "operator void" not invoked with cast syntax?为什么不使用强制转换语法调用“operator void”? 【发布时间】:2011-05-01 04:21:11 【问题描述】:在玩user GMan 的this answer 时,我制作了以下sn-p(用Visual C++ 9 编译):
class Class
public:
operator void()
;
Class object;
static_cast<void>( object );
(void)object;
object.operator void();
在使用调试器后,我发现转换为void
不会调用Class::operator void()
,只有第三次调用(显式调用运算符)实际上调用了运算符,这两个强制转换什么都不做。
为什么operator void
不使用强制转换语法调用?
【问题讨论】:
我喜欢你总是问奇怪但有趣的问题;)这是我的 +1。 您希望在没有演员的情况下执行什么代码?实际上没有...为什么要改变这个? @Eiko:如果那是operator int()
而我写了(int)object;
,那么operator int()
将被调用。原来operator void()
不是这种情况,所以我问了这个问题。
对于它的价值,Comeau 给出了以下警告:“Class::operator void()”将不会被调用以进行隐式或显式转换”。
和 gcc 警告:conversion to void will never use a type conversion operator
【参考方案1】:
技术原因见 §12.3.2:
转换函数永远不会用于将(可能是 cv 限定的)对象转换为(可能是 cv 限定的)相同的对象类型(或对它的引用),转换为该对象的(可能是 cv 限定的)基类类型(或对它的引用),或(可能是 cv 限定的)void。
理由是(可能)允许 §5.2.9/4 起作用:
任何表达式都可以显式转换为“cv void”类型。表达式值被丢弃。
(void)expr
假设对 any 表达式的结果值不做任何事情,但如果它调用您的转换运算符,它不会丢弃任何东西。所以他们禁止在转换中使用operator void
。
为什么不让转换类型 ID 为 void
的格式不正确呢?谁知道呢,但请记住,它并非完全没用:
struct foo
operator void()
std::cout << "huh?" << std::endl;
;
typedef void (foo::*void_function)();
foo f;
void_function func = &foo::operator void;
(f.*func)(); // prints "huh"
f.operator void(); // also does (which you knew)
它在技术上仍然对某些东西有用,所以也许这足以说明它不符合格式。
【讨论】:
“为什么不将转换类型 ID 设置为void
格式不正确?” 可能是因为 void
可能隐藏在 typedef 或模板参数?
@dyp,这就是 not ill-formed 的问题:意外行为:您希望转换运算符转换,但这个永远不会那样做。使其格式错误将有助于假定模板库的开发人员及早发现错误。但是,至少现在编译器会针对这种情况发出警告。
@GreenScape 有些用例你不关心它不会被调用,而使用ill-formed
,你必须生成特殊情况。就像f(future.get())
对应future<void>
。
此外,到void
的标准转换应该胜过任何用户定义的转换。以上是关于为啥不使用强制转换语法调用“operator void”?的主要内容,如果未能解决你的问题,请参考以下文章