Подтвердить что ты не робот

Boost make_shared принимает значение const. Любой способ обойти это?

Я использую boost-указатели в моей программе, и у меня есть класс, который принимает в качестве параметров ссылку на другой объект. Проблема, с которой я столкнулся, заключается в том, что функция make_shared требует, чтобы все параметры были ссылкой на const, и я получаю ошибки компиляции, если мой конструктор классов не разрешает передавать ссылочные параметры const.

Кто-нибудь знает причину этого? Кроме того, есть ли что-нибудь, что я могу сделать, чтобы обойти это?

пример кода того, что вызывает у меня проблемы:

class Object
{
  public:
    Object(int& i)
    {
      i = 2;
    }
};


int main(int argc, char *argv[])
{
  int i = 0;
  boost::shared_ptr<Object> obj = boost::make_shared<Object>(i);
  return 1;
}

В результате возникает ошибка компилятора, в которой указано следующее

: make_shared.hpp: 185: ошибка: нет соответствующей функции для вызова объекта Object:: Object (const int &) ' примечание: кандидаты: Object:: Object (const Object &) note: Object:: Object (int &)

Если параметр конструктор объектов является константой int, это работает. Мне любопытно, почему make_shared ведет себя таким образом.

4b9b3361

Ответ 1

http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/make_shared.html говорит: "Если вам нужно передать неконстантную ссылку на конструктор T, вы можете сделать это, обернув параметр в вызове boost:: ref." Другой текст на этой странице, похоже, поддерживает ответ Рюдигера Ханке.

Ответ 2

Невозможно говорить для авторов его функций, но... вы должны сделать выбор. Если бы функция использовала неконстантную ссылку, вы не могли бы передавать объекты const конструкторам, которые принимают ссылки на const.

По моему опыту, конструкторы, принимающие ссылки на const, гораздо более распространены, чем конструкторы, принимающие изменчивые ссылки.

Конструкторы могут иметь параметры n, поэтому вы не можете просто предоставить одну перегрузку, но должны учитывать любую комбинацию const/non-const, которая приводит к экспоненциальному взрыву перегрузок, который вам нужен, если вы 'd хочу обеспечить перегрузку для всех из них. С++ 0x и идеальная пересылка должны обеспечить решение этой проблемы, я думаю.

Ответ 3

До тех пор, пока ссылки на значения (см. Раздел "проблема пересылки") не появятся в С++ 0x, совершенная пересылка практически невозможна. make_shared просто делает все возможное с тем, что он дал.

Ответ 4

Вам нужно определить конструктор копирования.

class Object
{
  public:
    Object(const Object& original)
    {
        // Copy original to new object
        // The reason for the const is this should not change the original 
    };

    Object(int& i)
    {
      i = 2;
    }
};

Ответ 5

Пока я до сих пор не знаю, почему boost make_shared налагает на меня это ограничение, я нашел способ обойти его. Если я передам ссылку const на указатель параметра, я могу изменить указатель. Вот фрагмент кода:

class Object
{
  public:
    Object(int* const& i)
    {
      *i = 2;
    }
};


int main(int argc, char *argv[])
{
  int i = 0;
  boost::shared_ptr<Object> obj = boost::make_shared<Object>(&i);
  cout << i << "\n";
  return 1;
}

Это работает как шарм. У кого-нибудь есть идея, почему мне нужно прыгать через эти обручи? Кажется странным, что make_shared навязывает мне это ограничение, хотя я согласен, что это, вероятно, плохая идея в большинстве случаев.

Ответ 6

Возможно, вы сможете исправить это, создав конструктор Object explicit.