2

假设我有一些模板类

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) 为什么要删除此功能/错误?我想我在某处读到这是由于与“概念”的冲突。

但是,我再也找不到合适的参考资料了。有人有更好的记忆或书签吗?

4

2 回答 2

3

a) 在某些草案中允许这样做是否正确?

是的,它在所谓的“右值引用 1.0”中是允许的(参见N2118)。

b) 为什么要删除此功能/错误?我想我在某处读到这是由于与“概念”的冲突。

它被删除是因为将右值引用绑定到左值可能会导致在存在概念时违反“类型安全重载原则”:

每个函数都必须是独立的类型安全的,而不考虑它是如何被重载的。

例如,如果我们定义以下重载:

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)。

于 2012-10-03T01:45:06.407 回答
0

从 Andrew 的回答中获得信息,我还找到了一些关于该主题的非常易读的文章(rvalue-/lvalue-references),其中还提供了有关事情在这方面如何演变的参考。

于 2012-10-03T19:33:14.430 回答