一个简单的方法是提供一个接受左值引用的已删除成员:
template<typename T> void receive_ownership(T&) = delete;
这总是更适合左值参数。
如果您有一个带有多个参数的函数,所有这些参数都需要是右值,我们将需要几个已删除的函数。在这种情况下,我们可能更喜欢使用 SFINAE 对任何左值参数隐藏函数。
使用 C++17 和 Concepts TS 可以做到这一点:
#include <type_traits>
template<typename T>
void receive_ownership(T&& t)
requires !std::is_lvalue_reference<T>::value
{
// taking file descriptor of t, and clear t
}
或
#include <type_traits>
void receive_ownership(auto&& t)
requires std::is_rvalue_reference<decltype(t)>::value
{
// taking file descriptor of t, and clear t
}
再进一步,您可以定义自己的新概念,如果您想重复使用它,或者只是为了更加清晰,这可能会很有用:
#include <type_traits>
template<typename T>
concept bool rvalue = std::is_rvalue_reference<T&&>::value;
void receive_ownership(rvalue&& t)
{
// taking file descriptor of t, and clear t
}
注意:对于 GCC 6.1,您需要将 -fconcepts 传递给编译器,因为它是 C++17 的扩展,而不是它的核心部分。
为了完整起见,这是我的简单测试:
#include <utility>
int main()
{
int a = 0;
receive_ownership(a); // error
receive_ownership(std::move(a)); // okay
const int b = 0;
receive_ownership(b); // error
receive_ownership(std::move(b)); // allowed - but unwise
}