率直に言って、変数がどちらかであるかどうかは、これが変化する可能性がある場合よりも混乱が少ないと思います。const
これについて少し詳しく説明します。通常、これを行う理由は、const
変数を思い通りに初期化できないためです。std::vector
はこれの良い例です。さて、次の標準では、これを可能にする普遍的な初期化構文が導入されています。
const std::vector<int> cvi = { 1, 2, 3, 4, 5, 42 };
ただし、手元に C++1x のものがなくても、この初期化構文を許可しない型であっても、必要なことを行うヘルパー関数をいつでも作成できます。
const std::vector<int>& cvi = create_my_vector();
または、派手になりたい場合:
const std::vector<int>& cvi = compile_time_list<1,2,3,4,5,42>::create_vector();
に注意してください&
。関数呼び出しの結果をコピーしても意味がありません。右辺値をconst
参照にバインドすると、その有効期間が参照の有効期間の終わりまで延長されるためです。
もちろん、C++1x の移動セマンティクスをサポートするコンパイラで再コンパイルすると、そのような最適化はほとんど不要になります。ただし、rvlaue をconst
参照にバインドすることは、ベクトルを移動するよりも高速である可能性があり、遅くなる可能性はほとんどありません。
C++1x では、これをその場で実行するラムダ関数を作成することもできます。C++ は、信じられないほど膨大な数のツールを提供します。IME、あなたがいくら考えても、同じことをする別のアイデアを誰かが思いつくはずです。そして、多くの場合、あなたのものよりも優れています。
ただし、IME では通常、コードが多すぎて関数が少なすぎる場合にのみ、この問題が発生します。そして、これは constness だけでなく、同様の特性 (参照が参照するものなど) にも適用されます。
古典的なのは、複数の可能なストリームのうちの 1 つを使用することです。これの代わりに
int main(int argc, char* argv[])
{
std::istream* istrm = NULL;
std::ifstream ifs;
if( argc > 1 )
{
ifs.open( argv[1] );
if( ifs.good() )
istrm = &ifs;
}
if( !istrm )
istrm = &std::cin;
while( istrm->good() )
{
// reading from *istrm implemented here
}
return 0;
}
懸念事項を 1) どこから読み取るかを把握することと 2) 実際の読み取りに分割するだけです。
int read(std::istream& is)
{
while( is.good() )
{
// reading from is implemented here
}
return 0;
}
int main(int argc, char* argv[])
{
if( argc > 1 )
{
std::ifstream ifs( argv[1] );
if( ifs.good() )
return read(ifs);
}
return read(std::cin);
}
懸念を分離することによって修正できなかった、可能な限り一定ではなかった変数の実際の例をまだ見たことがありません。