【问题标题】:Overload function for rvalues and lvalues右值和左值的重载函数
【发布时间】:2015-01-30 13:31:34
【问题描述】:

我正在编写一个库,它使用共享指针来构建复杂的节点结构。由于结构中可能存在循环,并且为了避免内存泄漏,我决定在构建结构时采用以下策略:每当传递一个临时对象时,我使用 shared_ptr (获取所有权);每当我传递一个左值时,我都会使用一个weak_ptr。根据我的分析和库接口的设计方式,这应该完全避免循环。

但是,我在使用函数重载来了解参数是右值还是左值时遇到了问题。这是我得到的错误的一个非常简化的示例:

#include <iostream>
#include <memory>

using namespace std;

class MyClass {
public:
    int a;
    // this class contains some pointers to the node structure
};

MyClass fun(MyClass &&x, MyClass &&y)
{
    // should produce an object that has ownership of the two others
}

MyClass fun(MyClass x, MyClass y)
{
    // should not take ownership, but just copy the pointer
}

int main()
{
    MyClass x, y;

    fun(x, y);
    fun(MyClass(), MyClass());
}

使用 g++ 4.8.2 编译时出现以下错误:

example.cpp: In function ‘int main()’:
example.cpp:29:29: error: call of overloaded ‘fun(MyClass, MyClass)’ is ambiguous
     fun(MyClass(), MyClass());
                             ^
example.cpp:29:29: note: candidates are:
example.cpp:12:9: note: MyClass fun(MyClass&&, MyClass&&)
 MyClass fun(MyClass &&x, MyClass &&y)
         ^
example.cpp:18:9: note: MyClass fun(MyClass, MyClass)
 MyClass fun(MyClass x, MyClass y)
         ^

所以,显然编译器无法区分这两个调用。我认为右值函数优先于传值函数,但显然我错了。

另外:我不能声明函数接受 const 引用,因为我只想获得所有权,然后随意修改对象,所以引用不应该是常量。

关于如何解决这个问题的任何想法?

【问题讨论】:

  • 我明白了,但是如果我定义fun(const MyClass &amp;a, const MyClass &amp;b),编译器会很高兴。因此,显然在第二种情况下,编译器可以看到差异并优先考虑其中一种。
  • 要么有一个函数取值并从中移动,要么有两个函数,一个取左值引用并复制,一个取右值引用并移动。不要混合这两种模式。

标签: c++ c++11 overloading rvalue


【解决方案1】:

变化:

MyClass fun(MyClass x, MyClass y)
MyClass fun(MyClass&& x, MyClass&& y)

收件人:

MyClass fun(MyClass& x, MyClass& y)      // for lvalues
MyClass fun(MyClass&& x, MyClass&& y)    // for rvalues

在您的原始示例中,临时 MyClass 可以绑定到值或右值引用(两者都是完全匹配的)。但随着变化,没有歧义。

【讨论】:

  • 我试过了,但正如我在问题中所写,我需要稍后修改节点,所以我不能传递 const 引用(因为指向的对象将被分配给非 const 指针)
  • @knulp 您可以安全地删除const
  • 没有 const 的例子可以正常工作。谢谢! @Barry,如果您修改答案以删除 const,我将接受并投票。
  • 是的,不知道我为什么这样做。固定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
相关资源
最近更新 更多