常量引用、作为参数的构造函数和可编译性
const references, constructors as parameter, and compilability
一位同事让我查看他正在编写的一些代码,并遇到了特定行的问题,编译器(g++)会抱怨函数调用没有基于其参数的匹配函数。
在以两种方式解决问题后(一种是将参数移动到其自己的变量并传递它,接下来是更改参数列表以将其作为常量引用),我不得不问这个问题:为什么解决方案是这样的? 正如我的同事所说,我不满足于将其注销,就好像隐藏了一些构造函数细节一样。
结果,我将问题复制并简化为以下内容(使用 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;
}
我可能在这里错过了一些非常基本的东西,但是谁能向我解释为什么编译器认为不可编译的行没有匹配的函数调用?
提前谢谢。
原因很简单,临时值(如 SomeChild()
的值)不能绑定到非常量左值引用。虽然这没有深刻的技术原因,但这是一种设计选择:非常量引用通常用于修改被引用的东西,如果那个东西是暂时的,那么修改基本上不会产生持久的影响,这几乎总是逻辑错误。
只需将"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)
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 构造函数和 G++ 编译配方的问题
- 编译时生成应在构造函数中创建的非 constexpr 对象数组
- 线程构造函数周围的可变参数模板包装器无法编译
- C++根据调用的构造函数强制编译时错误
- 编译错误:临时对象构造函数中缺少参数
- 为什么删除默认构造函数 A::A() 时会编译"A a{};"?
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- std::具有initializer_list和size的unordered_map构造函数在main中编译,但不在类定
- 继承的构造函数,在 clang++3.9 中编译,在 g++ 7 中失败
- 为什么在使用转换构造函数编译代码时需要 const 复制构造函数?
- 将参数传递给 c++ 构造函数时出现 VS 编译错误
- 使用 -pedantic 编译时采用 std::reference_wrapper 的不明确构造函数
- 编译如何选择要拨打的构造函数
- 编译时构造函数选择
- C++编译错误是由于使用 std::move 时运动构造函数与其他非运动构造函数之间的冲突
- 显式复制构造函数编译错误
- 如何让g++使用move构造函数编译c++11代码
- C++复制构造函数编译错误