Rvalue and SFINAE Links

I recently started using rvalue links, and I came across a situation where I do not understand why they work the way they are.

I am trying to determine if a type can have begin and end . The code below gives the expected results if I change foo to accept its parameter by value or constant reference, but I'm not sure why it does not work when using the rvalue reference, and I was wondering if anyone could tell me why .

 #include <vector> #include <type_traits> #include <iostream> template<class Container> auto begin(Container &&c) -> decltype(c.begin()) { return c.begin(); } template<class Container> auto end(Container &&c) -> decltype(c.end()) { return c.end(); } template<class T, size_t size> T *begin(T (&array)[size]) { return (&array[0]); } template<class T, size_t size> T *end(T (&array)[size]) { return (&array[0] + size); } template <typename T> struct has_begin_end { typedef char true_type; typedef char false_type[2]; template <typename U> static true_type& test(decltype(begin(*((U*)0))) *b = 0, decltype(end(*((U*)0))) *e = 0); template <typename U> static false_type& test(...); enum { value = (sizeof(true_type) == sizeof test<T>(0)) }; }; template<class T> void foo(T &&t) { std::cout << has_begin_end<T>::value << std::endl; } int main() { std::vector<int> v = {1, 2}; std::cout << has_begin_end<std::vector<int> >::value << std::endl; std::cout << has_begin_end<int>::value << std::endl; foo(v); foo(123); } 
+4
source share
1 answer

This is because T is obtained as a reference type of lvalue when foo is called with lvalue. Try:

 has_begin_end<typename remove_reference<T>::type>::value 
+6
source

All Articles