2010-08-04 9 views
11

Чтобы добавить const к объекту non-const, который является предпочтительным методом? const_cast<T> или static_cast<T>. В недавнем вопросе кто-то упомянул, что они предпочитают использовать static_cast, но я бы подумал, что const_cast сделает код более понятным. Итак, каков аргумент для использования static_cast для создания переменной const?const_cast vs static_cast

ответ

14

Не используйте также. Инициализировать константную ссылку, которая ссылается на объект:

T x; 
const T& xref(x); 

x.f();  // calls non-const overload 
xref.f(); // calls const overload 

Или используйте шаблон в implicit_cast функции, как the one provided in Boost:

T x; 

x.f();       // calls non-const overload 
implicit_cast<const T&>(x).f(); // calls const overload 

Учитывая выбор между static_cast и const_cast, static_cast, безусловно, предпочтительнее: const_cast должен используется только для отбрасывать constness, потому что это единственный актер, который может это сделать, и отбрасывание констебрии по своей сути опасно. Изменение объекта с помощью указателя или ссылки, полученной путем отбрасывания константы, может привести к неопределенному поведению.

+0

Большинство слепков может быть "опасным". – curiousguy

+0

Скотт Мейерс дает пример использования 'static_cast' для' const', за которым следует 'const_cast', чтобы вызвать версию' 'operator''' '' '' '' '' '' '' ', чтобы вызвать версию' const'. Может ли это быть достигнуто с использованием ссылки const? –

+0

Похоже, что вы * можете * заменить 'static_cast', создавая новую ссылку на константу, но, конечно же, вы должны использовать' const_cast' для возврата неконстантной ссылки. Я не уверен, что это поведение, связанное с компилятором или платформой, или, если это подразумевается под любым из требований стандарта. –

2

Я бы сказал, что static_cast является предпочтительным, так как только позволит вам отлиты из не- const к const (который безопасен), а не в другом направлении (которое не обязательно безопасно).

+0

Это похоже на мнение Скотта Мейерса; см. «Эффективный C++ _», пункт 3, в примере «Избегать дублирования ...». –

1

Вы можете написать свой собственный бросок:

template<class T> 
const T & MakeConst(const T & inValue) 
{ 
    return inValue; 
}