假设我有一些模板化的课程
template <typename T>
struct Dummy {
// ...
};
我想重载一个函数'foo',使它接受一个左值
或它的右值参考。我可以使用一些IsDummy
特征来做到这一点
如下:
template <typename A>
std::enable_if<IsDummy<A>::value, void>
foo(A &&dummy)
{
// ....
}
IIRC在某些C ++ 11草案中是合法的
template <typename A>
foo(Dummy<A> &&dummy)
{
// ....
}
会同时接受左值和左值参考。
现在我的问题:
a)在某些草案中允许它是否正确?
b)为什么要删除此功能/错误?我想我读到的地方是因为与“概念”发生冲突。
但是,我找不到适当的参考资料了。有人有更好的记忆或书签吗?
答案 0 :(得分:3)
a)在某些草案中允许它是否正确?
是的,它被称为“rvalue references 1.0”(见N2118)。
b)为什么删除此功能/错误?我想我读到的地方是因为与“概念”发生冲突。
它已被删除,因为绑定对左值的右值引用可能会导致在存在Concept时违反“类型安全重载原则”:
每个函数必须孤立地保持类型安全,而不考虑它是如何过载的。
例如,如果我们定义以下重载:
template< CopyConstructible T > void f( T const & t ); // #1
template< MoveConstructible T > void f( T && t ); // #2
然后用可复制的左值调用f
将选择#1。但是,如果T是不可复制的类型(例如std::unique_ptr
),则#1不是可行的重载,因此编译器必须选择#2,可能在没有警告的情况下从左值中窃取资源。
有关详细信息,请参阅“右值引用2.0”(N2844)。
答案 1 :(得分:0)
得到安德鲁答案的信息后,我还发现了一些非常readable article的主题(rvalue- / lvalue-references),这也提供了关于事情在这个问题上如何演变的参考。