ふるつき

私は素直に思ったことを書いてるけど、上から目線だって言われる

inline namespaceに取り組む(わかってない)

今朝、ふざけてこんなツイートをしました。

 そうていしていた反応

 なんか知らないワードが飛んできました。

 このinline namespaceが???となったので調べます。


  • C++11で新しく追加された機能らしい
  • 名前空間を指定してもしなくても怒られないらしい

という機能のようです。??なので、コードを書きます。

#include <iostream>

namespace test {
  namespace test2 {
    const char* piyo =  "piyo";
  }
  const char* hoge = "hoge";
}

int main() {
  std::cout << test::hoge << std::endl <<
    test::test2::piyo << std::endl;
  return 0;
}

 ふつうです。test2をinline namespaceにすると、こう書けます。

#include <iostream>

namespace test {
  inline namespace test2 {
    const char* piyo =  "piyo";
  }
  const char* hoge = "hoge";
}

int main() {
  std::cout << test::hoge << std::endl <<
    test::piyo << std::endl;
  return 0;
}

test2::って書いてません。これが、test::test2::piyoでも同じ動作をするようです。これがinline namespaceです。ところがどっこい、私はusing namespaceの話をしていたわけです。これusing namespaceしてないです。しましょう。

#include <iostream>

namespace test {
  inline namespace test2 {
    const char* piyo =  "piyo";
  }
  const char* hoge = "hoge";
}

int main() {
  using namespace test;
  std::cout << test::hoge << std::endl <<
    test::piyo << std::endl;
  return 0;
}

 test::hogehogeと書いても良いですし、test::piyoはtest::test2::piyoでもtest2::piyoでもpiyoでもよいです。別にinline namespaceはusing namespaceされるときのことを考えているわけではないようです。私は多分ここを勘違いして???ってなっていました。

つかいかた(たぶん)

 いろいろ寄り道していますが、多分こうやって使うよね、というものを。

コードは上記のやつで多分okです。test2っていうのを作って、まだこれは決定ではないんだけれどもtestと同じようにあつかいたい、というときに使うのではないかな、と。そんな場面が存在するのですねきっと。と、おもってぐぐっていたら、std::tr1とstdを一緒に扱う、といったコードが出てきました。なるほど。

 じゃあきっとこういう使い方もしますね(きっと)。

#include <iostream>

namespace test {
  namespace test2 {
    const char* piyo =  "piyo";
  }
  const char* hoge = "hoge";
}

namespace test {
  inline namespace test2 {
  }
}

int main() {
  using namespace test;
  std::cout << test::hoge << std::endl <<
    test::piyo << std::endl;
  return 0;
}

test2名前空間の定義(宣言?)とは違うところでtest2をinline namespaceだと言い張ります。お家のgcc(5.2.0)だとこれでコンパイル通ります。なるほどよっしゃわかりました。

9/17 17:00修正

 先ほどTwitterでリプライをいただきまして、やはり、↑のプログラムはC++の規格的には違法だそうです。そうですよね。関数にあとからconstつけるようなものだ(これであとからconstつけられたら本当におもしろい)。

 さらに、よくわかる資料まで紹介していただきました。どうやらBoost.勉強会で発表されたもののようです。23ページあたりから具体的にinline namespaceがでてきてますね。

www.slideshare.net

結論

 ヘッダでusing namespace std;するなら、せめてinline namespace std{}しましょう。なんでや。良さがわかりません