Почему не shared_ptr <a> неявный конвертировать в shared_ptr <a const>?

Я попытался ввести некоторую корректность const (фактически функциональные парадигмы) к некоторому новому коду и обнаружил, что я не могу передать std::shared_ptr<A> функции, ожидающей std::shared_ptr<A const>. Обратите внимание, что я не хочу отбрасывать константу, но вводить ее, что является законным с исходными указателями.

Есть ли способ обойти это? Я не нашел функцию-член для этого.


Точная ошибка, произнесенная g++ 4.6.1, такова:

error: no matching function for call to ‘foo(std::shared_ptr<A>)’
note: candidate is:
note: template<class T> std::shared_ptr<_Tp> foo(std::shared_ptr<const _Tp>)

Ответ 1

Проблема в вашем случае не связана с возможными преобразованиями из/в разные std::shared_ptr, но больше связана с тем, как работает вывод типа для функций шаблона.

Когда компилятор пытается сопоставить вызов функции с шаблоном, он будет принимать только соответствия точные, т.е. никаких преобразований типов вообще. В этом случае ваша функция принимает std::shared_ptr<const T>, а вызывающая сторона имеет std::shared_ptr<U>, где U не const. Поскольку совпадение не точное, оно отбрасывает шаблон и выбирает следующего кандидата перегрузки.

Простые обходные пути: избегайте типичного вывода и предоставляйте аргумент шаблона:

std::shared_ptr<A> p;
foo<A>(p);             // will use the templated shared_ptr conversion

Или выполните преобразование самостоятельно:

foo(std::shared_ptr<const A>(p));