私たちは現在、次のようなC++ソースコードの意味と背景を考えています。前回の説明内容を反映し、ソースコードの一部を変更しています。なお、64ビットへの対応コードも含まれていますが、この連載では64ビット環境への対応については説明いたしません(参考のために掲載しています)。
#include <iostream>
int main()
{
const std::string ch0 = "Typical: I don't know anything about programming!\n";
const std::string ch ("Simplified form: I don't know anything about programming!\n");
const std::string* ch1 = new std::string ("Pointer form: I don't know anything about programming!\n");
std::cout << "Popular: I don't know anything about programming!" << std::endl;
std::printf(ch0.c_str()); // 前回記事を参照してください。
std::cout << ch.data();
std::cout << ch1->data();
std::cout << ch.c_str();
std::cout << ch1->c_str();
std::cout.write(ch.c_str(), ch.size());
std::cout.write(ch1->c_str(), ch1->size());
// 64ビットへの移植を予定しているときには次のコードを使う
// std::cout.write(ch.c_str(), std::streamsize(ch.size()));
// std::cout.write(ch1->c_str(), std::streamsize(ch1->size()));
delete ch1;
return int(0);
}
このC++ソースコードは、私たちに次のいずれかの印象を与えます。すでに説明済みの項目は、打ち消されています。
印象1:とにかく難しい!
印象2:Cのソースコードとどこか似ている
印象3:#includeに続くiostreamという意味が分からない
印象4:stdio.hがないにもかかわらず、printf関数が呼び出されていることが不思議だ!
印象5:std::coutのstdの意味が分からない
印象6:std::coutの「::」の意味が分からない
印象7:std::coutのcoutの意味が分からない
印象8:「<<」の意味が分からない
印象9:std::endlのendlの意味が分からない
印象10:「std::string ch」のstringの意味が分からない
印象11:「std::string ch」のchの意味が分からない
印象12:ch.data()の意味が分からない
印象13:ch.c_str()の意味が分からない
印象14:std::cout.writeの意味が分からない
印象15:ch.size()の意味が分からない
印象16:std::string*の「*」の意味が分からない
印象17:std::string* ch1の「ch1」の意味が分からない
印象18:ch1->data()の意味が分からない
印象19:ch1->c_str()の意味が分からない
印象20:ch1->size()の意味が分からない
今回は、「印象5:std::coutのstdの意味が分からない」の意味を考えます。stdは、standardの略語です。機能的には、「cout」を修飾するものです。たとえば、単に「豊田」といった場合、「どこの豊田」か分かりません。しかし、「"IT談話館の"豊田」と言えば、"あの豊田か"と豊田の意味がはっきりします。この場合、「"IT談話館の"」は、「std」と同じ機能を持つことになります。結論としては、「std」は「cout」の意味を鮮明にする、という機能を果たしています。なお、stdに続く「::」は、スコープ解決子などと呼ばれているようです。「"IT談話館の"豊田」の「の」に相当すると考えておきましょう。皆さんの中には、なんとなく難しいことが説明されている印象を持っている人もいるでしょうが、「"IT談話館の"豊田」を「"人事部"の豊田」に置き換えてみてください。「印象5:std::coutのstdの意味が分からない」ということは"ないはずです"。
「std」は、専門的には、名前空間名といわれます。難解な印象を受ける表現ですが、実際のところは、私たちの日常経験から得た知恵の一つにすぎません。ちなみに、名前空間という概念はCの世界には(明確な形では)ありません。この事実一つを取ってみても、CとC++の違いがはっきりします。参考のために、次の情報を紹介しておきます(なんとなく感じをつかむようにしてください)。
#if defined(__cplusplus)
#define _STD_BEGIN namespace std {
#define _STD_END }
ご覧のように、「#if defined(__cplusplus)」(Cではなく、C++の場合、という意味です)という条件が設定されています。この条件の意味するところはなんとなくお分かりになると思います。stdという名前空間はC++標準化委員会が定めていますが、私たちは自分独自の名前空間を定義することができます。名前空間の詳細については、本「IT談話館」のこの記事やChuck Allison氏のこの記事を参考にしてください。なお、上記ソースコードのVS.NETでのビルド結果はこのようになっています(VS.NETのバグのため、一部文字化けが発生しています)。