1

是否可以创建一个Wrapper

void f(void *) {}

Wrapper w;
f(w);

编译,但是

Wrapper w;
if (w) {}

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

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

4

2 回答 2

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 () { };
};

这是有效的,因为仅在重载解决的最后一步验证函数的可访问性。

于 2013-02-04T20:18:46.600 回答
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
    }
}

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

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

于 2013-02-04T20:31:36.163 回答