C++ では void* から他のポインタ型へ暗黙的に変換できない

今まで知らなかったので覚書。
C++ では void* 型から他のポインタ型へ暗黙的に変換することはできない。
なので、次のようなコードはエラーになる。

void* vp;

// error: cannot initialize a variable of type 'int *' with an lvalue of type 'void *';
int* p = vp;

これは C++ の仕様であって、C 言語であれば問題なく変換することができる。
なので、NULL の定義も C 言語であれば

#define NULL ((void*)0)

と、いう風に定義されている事が多いが、C++ だとこの定義ではポインタ型へと変換する事ができないので、単純に

#define NULL 0

という風に定義されている。
こんな違いがあったのは知らなかった。