I'm referring to this:
#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
}
Are there any other, shorter ways to accomplish the same?
For a moment I thought something like this could work
template<typename T>
auto f(decltype(std::declval<T>())&&) {}
but the IDE told me couldn't infer template argument 'T
', and I verified here, in the section Non-deduced contexts, that the expression of a decltype
-specifier is indeed a non-deduced context.
I'm interested also in a c++17 solution, if any exists.
template <std::rvalue_reference T> auto T(T&&) { }
. Simplified everywhere you can have a typename you can have a concept instead ofenable_if
– Henriettahenriettestd::rvalue_reference
is a thing. :c – Substagestd::is_rvalue_reference_v<T&&>
as!std::is_reference_v<T>
, and userequires
if this was C++20. Otherwise there's not much to change. I'm not a fan of the second overload, since it requires you to duplicate the function type. – Substageenable_if
on the return type, that way a user can't accidentally putint n; f<int, bool>(n)
, which overrides the type check. – Credulousis_rvalue_reference_v
(which is the actual spelling) is a variable template, not a concept, so you can't use it in this context. But even if you could,T
doesn't deduce as an rvalue reference in the rvalue case - so that constraint would reject everything (f(42)
deducesT=int
notT=int&&
, which is why OP checked ifT&&
was an rvalue reference type, notT
). – Ullrichis_rvalue_reference_v
for a reason. The type traits use the formis_something
withis_something_t
for the type andis_something_v
for the value., The corresponding concept is then generally namedsomething
orSomething
. The concept might not exists (yet?) in this case but if it did I would expect it to require thatT&&
is an rvalue reference and therefore work for the deducedT
. – Henriettahenriettervalue_reference<T>
existed as a concept, then surelyrvalue_reference<int>
would be false becauseint
is not an rvalue reference. – Ullrich