explicitで暗黙の型変換を防止する

先日書いた日記の補足。
以下のようなコードを書いてみると分かりますが、、、

#include <iostream>
#include <cassert>

using namespace std;

class M {
public:
  M(int i_):i(i_) { cout << "引数1個のコンストラクタだよ" << endl; } ;
  M(const M& m_):i(m_.i) { cout << "コピーコンストラクタだよ" << endl; }
  M &operator=(const M &o) { cout << "コピー代入演算子だよ" << endl; }

private:
  int i;
};

int main()
{
  M m1(1);     // (1)
  M m2 = 2;    // (2) 右辺値はM(2)に暗黙の型変換が行われる
  M m3 = M(3); // (3) (2)の記述と同じになる
}

暗黙の型変換が行われて、(2)と(3)の記述が同じになる。

わかりづらいのが以下の記事に書かれている例。
僕はC++を書いたころexplicitを使ったことがないへたれだった - 神様なんて信じない僕らのために

void hoge(M m_) {
    cout << "hoge:";
    m_.print();
}

こういうの定義して、

  hoge(m0);
  hoge(100); // これもOK


こんな書き方ができてしまう。これは分かりづらい><