boost make_shared接受一个const引用。有办法解决这个问题吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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&)注意:Object :: Object(int&)

如果Objects构造函数的参数是const int,则可以使用。我很好奇为什么make_shared会这样做。

答案

http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/make_shared.html说:“如果你需要将一个非const引用传递给T的构造函数,你可以通过将参数包装在对boost :: ref的调用中来实现。”该页面上的其他文字似乎支持RüdigerHanke的回答。

另一答案

不能代表他的作者,但是......你必须做出选择。如果函数将使用非const引用,则无法将const对象传递给采用const引用的构造函数。

根据我的经验,采用const引用的构造函数比采用可变引用的构造函数更常见。

构造函数可以有n参数,所以你不能只提供单个重载,但必须考虑const / non-const的任何组合,如果你想提供的话,这会导致你需要的过载指数爆炸所有这些都超载了。 C ++ 0x和完美转发应该为我认为的这个问题提供解决方案。

另一答案

直到rvalue references(参见标题为“转发问题”的部分)到达C ++ 0x,完全转发几乎是不可能的。 make_shared尽其所能,尽力而为。

另一答案

您需要定义一个复制构造函数。

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;
    }
};
另一答案

虽然我仍然不知道为什么提升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对我施加这种限制似乎很奇怪,尽管我同意大多数时候它可能是一个坏主意。

另一答案

您可以通过创建Object构造函数explicit来修复它。

以上是关于boost make_shared接受一个const引用。有办法解决这个问题吗?的主要内容,如果未能解决你的问题,请参考以下文章

在我的测试中,make_shared(boost 或 stl)似乎比 shared_ptr+new 稍慢

我应该如何在 io_service 中解决这个问题?

终止正在运行的 boost 线程

从非常量到常量模板参数的隐式转换在 boost::optional 中不起作用

boost::asio::acceptor - 在旧连接仍然打开时接受新的传入连接

如何接受boost :: asio :: ssl :: stream 作为boost :: asio :: ip :: tcp :: socket类型的参数