右值和左值引用的重载函数

问题描述 投票:0回答: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) 为什么删除此功能/错误? 我想我在某处读到这是由于与“概念”的冲突。

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

c++ c++11 rvalue-reference
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)。


0
投票

从安德鲁的回答中获得信息,我还发现了一些关于该主题的非常可读的文章(右值/左值引用),其中还提供了有关此事如何演变的参考。

© www.soinside.com 2019 - 2024. All rights reserved.