const T value
, где T
равно Object*
, равно Object* const value
. const
в const T value
применяется к value
и не изменяет T
. const T value
- это value
типа T
, который не может быть изменен, что для указателей означает, что нельзя назначить новый адрес. Ясно, что следующая функция не может быть вызвана с const Object *
.
int IndexOf(Object * const value) const // const pointer to non-const Object
Чтобы добавить const
ness к указанному типу, вы можете использовать черты типа, чтобы получить указываемый тип, добавить к нему const и затем создать из него новый тип указателя. Например:
#include <type_traits>
template<class T>
using add_const_to_ptr =
std::add_pointer_t<
std::add_const_t<
std::remove_pointer_t<T>>>;
Использование которого будет выглядеть так:
template<class T>
struct container {
void push(add_const_to_ptr<T> ptr) {
(void)ptr;
}
};
struct bar {};
int main()
{
const bar cbar;
bar mbar;
container<bar*> my_container;
my_container.push(&mbar);
my_container.push(&cbar);
}
Хотя предполагается, что container
будет использоваться только с указателями, в этом случае лучше сделать так, чтобы T
ссылался на тип объекта, на который указывает объект, а не на тип указателя. Если T
может быть или не быть указателем, черта типа может быть улучшена путем проверки, действительно ли T
указатель с std::conditional
:
#include <type_traits>
template<class T>
using add_const_to_ptr =
std::conditional_t<std::is_pointer<T>::value,
std::add_pointer_t<
std::add_const_t<
std::remove_pointer_t<T>>>,
T>;