1

Wrapper次のようなクラスを作成することは可能です

void f(void *) {}

Wrapper w;
f(w);

コンパイルしますが

Wrapper w;
if (w) {}

コンパイルされませんか?または、実行時に違いを検出しますか?

背景:win32はのHANDLEtypedefですvoid *。Win32は使用しませんNULLが、代わり((HANDLE)(-1))にエラー値として使用するため、暗黙的にaをboolにキャストするコードHANDLEは、ほぼ確実に間違ったことをテストしています。をラップするクラスが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 に答える