почему приведение умного указателя типа const к умному указателю типа работает

0

Любая идея, почему a1 = a2 не работает, но работает a2 = a1. Должна быть функция в шаблоне интеллектуального указателя, который выполняет преобразование? Который из них?

#include "stdafx.h"
#include<memory>
class TestClass
{
public:
    int a ; 

};
typedef std::shared_ptr<TestClass> TestSP;
typedef std::shared_ptr<const TestClass> TestConstSP;
int _tmain(int argc, _TCHAR* argv[])
{
    TestSP a1 = TestSP();
    TestConstSP a2 = TestConstSP();
    //a1 =a2; //error C2440: '<function-style-cast>' : cannot convert from 'const std::shared_ptr<_Ty>' to 'std::shared_ptr<_Ty>'       
    a2=a1;

    return 0;
}
  • 0
    Второй в этом списке (по-прежнему помечены # 1).
Теги:
templates
type-conversion
smart-pointers

2 ответа

0

Это связано с использованием const. Если у вас есть указатель const ' const_ptr ' и указатель non const ' non_const_ptr ', это нормально:

const_ptr = non_const_ptr; // const_ptr doesn't allow modifying the pointed value, while non_const_ptr does.

Но это запрещено:

non_const_ptr = const_ptr; // const_ptr is 'const'. Allowing non_const_ptr to modify the pointed value would'n respect the 'const' contract.

И следующее будет работать:

non_const_ptr = (type *) const_ptr; // You have the right to do that as you explicitely break the contract. 
                                    // The programmer is the boss. This is a bit ugly though.

Точно такая же логика применяется к вашему примеру.

0

Это интересно, и похоже, что MSVC реализовал стандарт для письма здесь. Само присваивание указано в §20.8.2.2.3 [util.smartptr.shared.assign]/p1-3:

shared_ptr& operator=(const shared_ptr& r) noexcept;
template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);

Эффекты: эквивалент shared_ptr(r).swap(*this).

Возвращает: *this.

[Примечание. Обновления подсчета использования, вызванные созданием и уничтожением временных объектов, не являются наблюдаемыми побочными эффектами, поэтому реализация может удовлетворять эффектам (и подразумеваемым гарантиям) с помощью различных средств без создания временного. <example omitted> ]

Соответствующий конструктор указан в §20.8.2.2.1 [util.smartptr.shared.const]/p17-19:

shared_ptr(const shared_ptr& r) noexcept;
template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;

Требуется: второй конструктор не должен участвовать в разрешении перегрузки, если Y* неявно конвертируется в T*.

Эффекты: если r пуст, создается пустой объект shared_ptr; в противном случае создается объект shared_ptr который имеет право собственности на r.

Постусловия: get() == r.get() && use_count() == r.use_count().

Поскольку const TestClass * неявно конвертируется в TestClass *, шаблонный конструктор не участвует в разрешении перегрузки, что делает shared_ptr(r) плохо сформированным, поскольку нет соответствующего конструктора.


Edit: Я вижу путаницу. VS2012 довольно плохо разработан для сообщений об ошибках компилятора. Полное сообщение об ошибке, испускаемое компилятором:

error C2440: '<function-style-cast>' : cannot convert from 'const std::shared_ptr<_Ty>' to 'std::shared_ptr<_Ty>'
      with
      [
          _Ty=const TestClass
      ]
      and
      [
          _Ty=TestClass
      ]

Важно отметить, что два _Ty в выводе ошибки относятся к разным типам. Окно списка ошибок в VS2012, однако, обрезает это только в первой строке и теряет эту важную информацию. Вы должны посмотреть на вывод сборки для полного сообщения об ошибке.

  • 0
    это объясняет преобразование между const std :: shared_ptr <TestClass> и std :: shared_ptr <TestClass>, но является std :: shared_ptr <const TestClass> таким же, как const std :: shared_ptr <TestClass>
  • 0
    Нет, преобразование происходит между shared_ptr<const TestClass> и shared_ptr<TestClass> . Верхний уровень const (как в const std::shared_ptr<TestClass> ) не имеет значения для преобразования. VS2013 выдает мне error C2440: '<function-style-cast>' : cannot convert from 'const std::shared_ptr<const TestClass>' to 'std::shared_ptr<TestClass>'

Ещё вопросы

Сообщество Overcoder
Наверх
Меню