配列の要素数を取得するだけのものを自分で書くならこんな感じかな。

template<class T, size_t N>
std::size_t size(T (&)[N]) {
return N;
}

実装自体には sizeof を使ったって害はあまりない (あえてする意味もないけど)。

template<class T, size_t N>
std::size_t size(T (&a)[N]) {
return sizeof a/sizeof a[0];
}

sizeof でのやり方を「そのまま」書く、またはマクロで覆うのは、
型チェックの支援を受けられないから変なミスをしやすい。

変数 a が (配列ではなく) ポインタのときに
sizeof(a)/sizeof(a[0]) という式がコンパイルは通っちゃったりするし。
変数名を二回書かなきゃならないのも、
何かの修正のときにうっかり片方だけ書き換えたりとか有りがち。

プログラミングをそれなりに長くやってると、
馬鹿みたいなつまらないミスをした経験のひとつやふたつやみっつや二百くらいはあるでしょ。
型システムはそういうのを多少なりとも事前に検出してくれるありがたい仕組みなんだから、
積極的に活用したいところ。