使用左值引用错误地调用了Rvalue引用构造函数
Rvalue reference constructor incorrectly called with an lvalue reference
编译此代码时:
class Base { /*...*/ };
class Derived : public Base { /*...*/ };
class C
{
public:
template<typename T>
C(T const& inBase) : baseInC(new T(inBase)) { /*...*/ }
template<typename T>
C(T&& inBase) : baseInC(new T(std::move(inBase))) { /*...*/ }
std::unique_ptr<Base> baseInC;
};
int main()
{
Base base;
Derived derived;
C ca(base);
C cb(derived);
C cc( (Base()) );
C cd( (Derived()) );
return 0;
}
我收到编译器的消息:
In instantiation of C::C(T&&) [with T = Base&]': required from C ca(base); error: new cannot be applied to a reference type
In instantiation of C::C(T&&) [with T = Derived&]': required from C cb(derived); error: new cannot be applied to a reference type
看起来C ca(base);
与右值引用ctor调用相关联。为什么编译器很难将这一行与第一个ctor关联起来?如果我注释掉有问题的行,那么cc
和cd
的构造就如预期的那样工作。
如果要复制或移动,请按值传递。以一种简化的方式:
template <typename T>
void foo(T x)
{
T * p = new T(std::move(x));
}
否则,如果您有一个像template <typename T> ... T &&
这样的通用引用,则可以将基类型获取为typename std::decay<T>::type
(来自<type_traits>
)。在这种情况下,您应该将参数作为std::forward<T>(inBase)
传递。
重载通用引用是个坏主意(参见Scott Meyer最近的演讲)。
C ca(base);
C cb(derived);
这些将调用模板化的通用引用构造函数,因为通用引用绑定到everything,并且由于base
和derived
没有作为const &
传入,所以它不会绑定到第一个构造函数。相反,编译器推断模板参数为Base & &&
和Derived & &&
,在引用折叠规则之后,您将得到最终调用错误的Base &
和Derived &
。
C cc( (Base()) );
C cd( (Derived()) );
这些工作是因为临时只能绑定到CCD_ 17,因此第一个构造函数是更好的匹配。
- 如何在 c# 代码中通过引用调用时从 c++ dll 更新数组值?
- 推理类型如何工作"auto"和按引用调用?
- C++ 通过引用调用函数
- 按引用调用与按指针参数调用的差异 前递增和后递增
- C++当您取消引用指向类对象的指针,然后将其作为引用返回时,是否可以对此引用调用方法
- 通过引用调用模板专用化
- 为什么通过带有文字编号的引用调用会出现"无匹配函数"错误?
- 按引用调用还是按值调用?
- 从 JS (V8) 中C++对象的引用调用函数
- 为什么要抛出引用调用复制构造函数的异常?
- 向量 - 通过引用 c++ 调用
- 为什么可以从常量引用调用析构函数
- 使用全局引用调用函数时访问冲突
- 引用调用在 c++ 中如何工作?
- 它不是编译.我正在调用一个通过引用调用的函数,但有一个错误,无法将双*转换为双倍
- C++函数调用 lambda obj,按值调用比按引用调用快
- 如何在 C++14 中编写用于调用 Fortran 函数的通用包装器(按引用调用 --按值调用>)
- 通过引用调用类对象的 2D 数组
- 构造函数参数中的引用调用引用的默认构造函数
- 如何在 main 中使用包含对节点的引用调用函数