ゆとりーなの日記

日記的な事を書いて行くと思はれる

ライブラリ版nullptrの悲劇

MSVC10用に書いていたコードをふとしたきっかけでgcc-4.5.1でコンパイルすることになって、nullptrどうしよう、とりあえず-Dnullptr=NULLでいいかーとか思っていたら、kikairoya先生からnullptrイディオムのリンクが飛んできたのであーやっぱりこれ使ったほうがいいのかねーとか思いながら実装を眺めてました。アドレス取れないようにoperator &をprivateにするのねとかなるほどなーと思いながら、こいつをどこかにこっそり書いておくかとキーボードに手を伸ばしたその刹那、boost.addressofとかいうものの存在が頭に浮かびました。なんかoperator &がオーバーロードされていてもアドレスが取れるとかいう代物が世の中にはあったのです。こいつにライブラリベースのnullptr突っ込んだら残念なことになるのではないかと試してみたら案の定なりました。

#include <iostream>
#include <boost/utility/addressof.hpp>

// 予約語とかぶっちゃうからmy_を付けとく
const class my_nullptr_t { 
 public:
  template<class T>
  operator T*() const {
    return 0;
  }
 
  template<class C, class T>
  operator T C::*() const {
    return 0;
  }
 
 private:
  void operator &() const; // アドレスを取得することができない?
 
} my_nullptr = {};

int main() {
  std::cout << boost::addressof(my_nullptr) << std::endl; // アドレスが取れました!
  return 0;
}

まぁ&nullptrはまだやりかねませんけど、よっぽどの悪意がない限りnullptrをaddressofに突っ込むといったことはやりそうにありませんから実用上はそれほど問題にならない気はしますが。
やっぱりnullptrは予約語になってくれてよかったです。はい。