0

一位同事让我查看他正在编写的一些代码,并遇到了特定行的问题,编译器 (g++) 会抱怨函数调用没有基于其参数的匹配函数。

在以两种方式解决问题后(一种是将参数移动到它自己的变量并传递它,接下来是更改参数列表以将其作为 const 引用),我不得不问这个问题:为什么解决方案是这样的它是?正如我的同事所说,我不满意把它写下来,好像一些构造函数的细节被隐藏起来了。

结果,我将问题复制并减少到以下问题(使用 g++ -Wall -ansi -pedantic 编译):

class SomeClass
{
   public:
      static void SomeFunction(SomeClass& sc) {}
      static void SomeFunction2(const SomeClass& sc) {}
};

class SomeChild : public SomeClass {};

void testOne(void)
{
   // this compiles
   SomeChild sc = SomeChild();
   SomeClass::SomeFunction(sc);

   // this doesn't compile
   //SomeClass::SomeFunction(SomeChild());
}

void testTwo(void)
{
   // this compiles
   SomeChild sc = SomeChild();
   SomeClass::SomeFunction2(sc);

   // this compiles
   SomeClass::SomeFunction2(SomeChild());
}

int main(void)
{
   testOne();
   testTwo();

   return 0;
}

我可能在这里遗漏了一些非常基本的东西,但是谁能向我解释为什么编译器认为无法编译的行没有匹配的函数调用?

提前致谢。

4

2 回答 2

3

原因很简单,临时值(例如 的值)SomeChild()不能绑定到非常量左值引用。虽然没有深层的技术原因,但这是一种设计选择:非常量引用通常用于修改所引用的内容,如果该内容是临时的,那么修改基本上不会产生持久的影响,这几乎是总是逻辑错误。

于 2013-11-02T17:06:01.437 回答
0

只需将 'SomeFunction2' 替换为 'SomeFunction':

#include <iostream>

class SomeClass
{
   public:
      static void SomeFunction(SomeClass& sc) { std::cout << "not const" << std::endl; }
      static void SomeFunction(const SomeClass& sc) { std::cout << "const" << std::endl; }
};

class SomeChild : public SomeClass {};

int main(void)
{
   SomeChild sc = SomeChild();
   SomeClass::SomeFunction(sc);
   SomeClass::SomeFunction(SomeChild());

   return 0;
}

一切都很好。

如果没有更改,您将临时绑定到引用,这是不可能的。唯一的选择是“T”、“const T&”或通用参考“T&&”(http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers

于 2013-11-02T17:10:15.990 回答