自动转换为指针而不自动转换为bool(类似)可能吗?

时间:2013-02-04 20:15:18

标签: c++

是否可以创建一个类Wrapper,以便

void f(void *) {}

Wrapper w;
f(w);

编译,但

Wrapper w;
if (w) {}

不编译?或者在运行时检测差异?

背景:win32 HANDLEvoid *的typedef。 Win32不使用NULL而是((HANDLE)(-1))作为错误值,因此任何隐式地将HANDLE强制转换为bool的代码几乎肯定会测试错误的东西。我有一个包装HANDLE的类,如果可能的话,我想在使用包装类时删除这个错误的机会。

2 个答案:

答案 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
    }
}

您无法直接传递包装器,但传递包装器的地址会将其转换为值的地址。

要非常小心如果您尝试将其与外部模板功能一起使用,因为它们可能无法正常运行。