Честно говоря, я нахожу это меньше сбивающим с толку, если переменная 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();
Обратите внимание на &
. Нет смысла копировать результат вызова функции, поскольку привязка значения r к ссылке const
продлевает его время жизни до конца времени жизни ссылки.
Конечно, перекомпиляция с компилятором, который поддерживает семантику перемещения C ++ 1x, сделает такие оптимизации практически ненужными. Но привязка rvlaue к ссылке const
может все же быть быстрее, чем перемещение вектора, и вряд ли будет медленнее.
С C ++ 1x вы также можете создавать лямбда-функции, делая это на лету. C ++ просто предоставляет невероятно огромный арсенал инструментов. IME, как бы ты ни думал, кто-то другой должен придумать еще одну идею сделать то же самое. И часто лучше, чем у вас.
Тем не менее, в IME эта проблема обычно сопровождается слишком большим количеством кода и слишком малым количеством функций. И тогда это относится не только к константности, но и к подобным чертам - например, к чему относится ссылка.
Классика - это использование одного из нескольких возможных потоков. Вместо этого
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);
}
Мне еще предстоит увидеть реальный пример переменной, которая не была бы такой же постоянной, как могла бы, которая не могла быть исправлена путем разделения проблем.