Попробуйте ls -U
или ls -f
.
ls
, по умолчанию, сортирует файлы в алфавитном порядке. Если у Вас есть 2 миллиона файлов, тот вид может занять много времени. Если ls -U
(или возможно ls -f
), то имена файлов будут сразу распечатаны.
Код на самом деле не будет работать в VC ++ - вы не обновляете значение (или, по крайней мере, не должно), отсюда и предупреждение от GCC. Правильный код -
const_cast<myType*&>(myMember) = new myType();
или [из другого ответа, спасибо: P]:
const_cast<ThisType*>(this)->myMember = new myType();
Эффективное изменение его означает, что вы получаете неявные const_cast
в функциях-членах const
, что обычно является к чему вы должны стремиться, когда обнаруживаете, что выполняете множество const_cast
на this
. Нет никаких других побочных эффектов при использовании изменяемого.
Как вы можете видеть из яростных дебатов вокруг этого вопроса, волевое использование mutable
и большого количества const_cast
определенно может быть симптомом неприятных запахов в вашем коде. С концептуальной точки зрения, отказ от константности или использование mutable
может иметь гораздо более серьезные последствия. В некоторых случаях правильным решением может быть изменение метода на неконстантный, т. Е. Признать тот факт, что он изменяет состояние.
Все зависит от того, насколько важна константная корректность в вашем контексте - вы не хотите в конечном итоге просто разбрызгивать изменяемый
, как пыльцу пикси, чтобы все работало, но изменяемый
предназначен для использования, если член не является частью наблюдаемого состояния объекта. Наиболее строгое представление о константной корректности будет заключаться в том, что ни один бит состояния объекта не может быть изменен (например, это может быть критично, если ваш экземпляр находится в ПЗУ ...) - в тех случаях, когда вам не нужна константность потеряться. В остальных случаях
Этот сценарий - инкапсулированное изменение внутреннего состояния, которое не влияет на внешнее состояние (например, результаты кэширования) - именно для этого используется ключевое слово изменяемое
.
const_cast
почти всегда является признаком ошибки проекта. В вашем примере либо func ()
не должно быть const
, либо myMember
должно быть mutable
.
Вызывающий func ()
ожидает, что ее объект не изменится; но это означает «не меняться так, как она может заметить»; то есть, чтобы не менять свое внешнее состояние. Если изменение myMember
не изменяет внешнее состояние объекта, это то, для чего предназначено ключевое слово mutable
; в противном случае func ()
не должно быть const
, потому что вы нарушите гарантии своей функции.
Помните, что mutable
не является механизмом для обхода const -корректность; это механизм его улучшения.
class Class{
int value;
void func()const{
const_cast<Class*>(this)->value=123;
}
};
Как написал Стив Гилхэм, mutable
- это правильный (и короткий) ответ на ваш вопрос. Я просто хочу намекнуть в другом направлении.
Может быть, в вашем сценарии можно использовать (или более одного) интерфейса?
Возможно, вы сможете понять это из следующего примера:
class IRestrictedWriter // may change only some members
{
public:
virtual void func() = 0;
}
class MyClass : virtual public IRestrictedWriter
{
public:
virtual void func()
{
mValueToBeWrittenFromEverybody = 123;
}
void otherFunctionNotAccessibleViaIRestrictedWriter()
{
mOtherValue1 = 123;
mOtherValue2 = 345;
}
...
}
Итак, если вы передадите некоторой функции IRestrictedReader *
вместо const MyClass *
, она может вызвать func
и, таким образом, измените mValueToBeWrittenFromEverybody
, тогда как mOtherValue1
является своего рода «const».
. Я считаю изменяемым
всегда чем-то вроде хака (но иногда его использую).