是否可以创建一个类Wrapper
,以便
void f(void *) {}
Wrapper w;
f(w);
编译,但
Wrapper w;
if (w) {}
不编译?或者在运行时检测差异?
背景:win32 HANDLE
是void *
的typedef。 Win32不使用NULL
而是((HANDLE)(-1))
作为错误值,因此任何隐式地将HANDLE
强制转换为bool的代码几乎肯定会测试错误的东西。我有一个包装HANDLE
的类,如果可能的话,我想在使用包装类时删除这个错误的机会。
答案 0 :(得分:6)
在C ++ 11中,可以使用已删除的函数。例如:
struct Wrapper
{
operator void* () { }
operator bool () = delete;
};
void foo(void*) { }
int main()
{
Wrapper w;
foo(w); // OK
if (w) // ERROR!
{
// ...
}
}
如果您使用的是不支持C ++ 11的编译器,则可以通过声明bool
转换运算符private
来获得相同的结果:
struct Wrapper
{
operator void* () { }
private:
operator bool () { };
};
这是有效的,因为函数的可访问性仅在重载解析的最后一步验证。
答案 1 :(得分:0)
嗯,这是一个有效的版本,但请记住,这是生产代码中的可怕的想法:
struct Wrapper {
void *_value;
Wrapper() : _value(NULL) {
};
template<typename T>
Wrapper(T *value) : _value(value) {
};
void *operator &() {
return _value;
};
};
void func(void *value) {
printf("%p", value);
}
int main()
{
Wrapper w = (void *) 0xFFAABB;
if (w) // error, 'No viable conversion from 'Wrapper' to 'bool'
{
func(&w); // 0xffaabb
}
}
您无法直接传递包装器,但传递包装器的地址会将其转换为值的地址。
要非常小心如果您尝试将其与外部模板功能一起使用,因为它们可能无法正常运行。