enable_if 是定义仅接受任何类型的右值的函数的最简洁方法吗?

Enr*_*lis 6 c++ templates template-meta-programming c++17 c++20

我指的是这个:

#include <utility>

template<typename T, typename = std::enable_if_t<std::is_rvalue_reference_v<T&&>>>
auto f(T&&) {}

int main(){
    int i{};
    f(std::move(i)); // ok
    f(int{1});       // ok
    f(i);            // compile time error, as expected
}
Run Code Online (Sandbox Code Playgroud)

还有其他更短的方法可以完成同样的任务吗?

有那么一刻我以为这样的东西可以工作

template<typename T>
auto f(decltype(std::declval<T>())&&) {}
Run Code Online (Sandbox Code Playgroud)

但 IDE 告诉我无法推断模板参数 ' T',我在非推导上下文部分中验证了-说明符的表达式确实是非推导上下文。decltype


解决方案感兴趣(如果存在)。

pao*_*olo 8

您是否尝试显式删除左值过载?

template <typename T>
auto f(T &&) {}

template <typename T>
auto f(T &) = delete;
Run Code Online (Sandbox Code Playgroud)


康桓瑋*_*康桓瑋 3

正如 @HolyBlackCat 评论的那样,您可以使用概念来简化函数签名

#include <type_traits>

template<typename T>
  requires (!std::is_lvalue_reference_v<T>)
auto f(T&&) {}
Run Code Online (Sandbox Code Playgroud)

或者通过检查接受左值引用的 lambda 表达式的有效性来检测左值或右值

#include <utility>

template<typename T>
  requires (!requires (T&& x) { [](auto&){}(std::forward<T>(x)); })
auto f(T&&) {}
Run Code Online (Sandbox Code Playgroud)