一种简单的方法是提供一个接受左值引用的已删除成员:
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
}