C++ 常量引用、构造函数作为参数和可编译性

C++ 常量引用、构造函数作为参数和可编译性,c++,oop,inheritance,constructor,g++,C++,Oop,Inheritance,Constructor,G++,一位同事让我查看他正在编写的一些代码,发现某一行有问题,编译器(g++)会抱怨函数调用没有基于其参数的匹配函数 在用两种方法解决问题后(一种方法是将参数移动到它自己的变量并传递它,另一种方法是更改参数列表以将其作为常量引用),我不得不问这个问题:为什么解决方案是这样的?正如我的同事所说,我不满足于把它写下来,就好像一些构造函数的细节被隐藏了一样 因此,我将问题复制并简化为以下内容(使用g++-Wall-ansi-pedantic编译): 我可能在这里遗漏了一些非常基本的东西,但是有人能向我解释为

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

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

因此,我将问题复制并简化为以下内容(使用g++-Wall-ansi-pedantic编译):

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


提前感谢。

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

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

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

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

只需将“SomeFunction 2”替换为“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;
}
#包括
上课
{
公众:

静态void SomeFunction(SomeClass&sc){std::cout只需将“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;
}
#包括
上课
{
公众:

静态void SomeFunction(SomeClass&sc){std::cout只需将“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;
}
#包括
上课
{
公众:

静态void SomeFunction(SomeClass&sc){std::cout只需将“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;
}
#包括
上课
{
公众:

静态void SomeFunction(SomeClass&sc){std::cout请记住,上面的示例是原始问题的简化变体,应该知道,这个特定函数调用只有一个用例(它使用了从boost::function派生的类)。在这种情况下,重载函数可能是毫无意义的。此问题与非常量引用有关。更改函数名将解决此问题,因为编译器将找到适当的重载。但是,在非平凡情况下,当两个函数应该执行不同的操作时,会发生什么?答案是肯定的不解释原因。对。'T'是不可取的,因为它会有效地浪费内存。'T&&'不幸的是,在C++98中不存在原始问题。请记住,上面的示例是原始问题的简化变体,应该知道,此特定函数调用只有一个用例(它采用了从boost::function派生的类)。在这种情况下,重载函数可能是毫无意义的。此问题与非常量引用有关。更改函数名将解决此问题,因为编译器将找到适当的重载。但是,在非平凡情况下,当两个函数应该执行不同的操作时,会发生什么?答案是肯定的不解释原因。对。'T'是不可取的,因为它会有效地浪费内存。'T&&'不幸的是,在C++98中不存在原始问题。请记住,上面的示例是原始问题的简化变体,应该知道,此特定函数调用只有一个用例(它采用了从boost::function派生的类)。在这种情况下,重载函数可能是毫无意义的。此问题与非常量引用有关。更改函数名将解决此问题,因为编译器将找到适当的重载。但是,在非平凡情况下,当两个函数应该执行不同的操作时,会发生什么?答案是肯定的不解释原因。对。'T'是不可取的,因为它会有效地浪费内存。'T&&'不幸的是,在C++98中不存在原始问题。请记住,上面的示例是原始问题的简化变体,应该知道,此特定函数调用只有一个用例(采用了从boost::function派生的类)。在这种情况下,重载函数可能毫无意义。此问题与非常量引用有关。更改函数名将解决此问题,因为编译器