const引用,构造函数作为参数和可编译性

时间:2013-11-02 16:54:48

标签: c++ oop inheritance constructor g++

一位同事让我查看他正在编写的一些代码并遇到了一个特定行的问题,编译器(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;
}

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

提前致谢。

2 个答案:

答案 0 :(得分:3)

简单的原因是临时值(例如SomeChild()的值)无法绑定到非常量左值引用。虽然没有深刻的技术原因,但这是一个设计选择:非常量引用通常用于修改被引用的东西,如果那是暂时的,那么修改基本上没有持久效果,这几乎是永远是逻辑错误。

答案 1 :(得分: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&amp;'或通用参考'T&amp;&amp;' (http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers