(C++の場合)VS2010の現在のクリアマクロは次のとおりです。
#define CLEAR(v) do { __pragma(warning(suppress: 4127 4836)) typedef std::remove_reference< decltype(v)>::type T; static_assert( std::is_pod<T>::value || (__has_trivial_constructor(T) && __has_trivial_destructor(T)), "must not CLEAR a non-POD!" ); static_assert( !std::is_pointer<T>::value, "pointer passed to CLEAR!" ); memset(&(v), 0, sizeof(v)); } while(0)
type_traits ヘッダーの内容を使用してバリアントを作成できます。
説明付きのフォーマットされたバージョン:
#define CLEAR(v) \
do { \
__pragma(warning(suppress: 4127 4836)) \
typedef std::remove_reference< decltype(v)>::type T; \
static_assert( \
std::is_pod<T>::value \
|| (__has_trivial_constructor(T) && __has_trivial_destructor(T)), \
"must not CLEAR a non-POD!" ); \
static_assert( !std::is_pointer<T>::value, "pointer passed to CLEAR!" ); \
memset(&(v), 0, sizeof(v)); \
} while(0)
if/else を含むすべての場所で本物の関数のように使用できるようにするための外側の do-while。
左辺値で機能するように Remove_reference が必要です。decltype だけでは int* と int*& が異なり、is_pointer は後者に対して false を報告します。
is_pod チェックは一般に適しています。追加の条件により struct A1 : A; が許可されます。A が POD で、A1 が POD メンバーのみを追加する場合の作業。is_pod の目的では false ですが、クリアするのも同じ意味です。
is_pointer チェックは、ポインタの間接化が間違っている場合や混乱して構造体のアドレスを渡した場合に、予想されるミスタイプをガードします。= NULL を使用してポインターをクリアしてください。;-)
は、それ以外の__pragma
場合に発行される L4 警告を抑制するためにあります。