Rvalue ссылки и SFINAE - PullRequest
       1

Rvalue ссылки и SFINAE

4 голосов
/ 15 апреля 2011

Я недавно начал использовать ссылки на rvalue, и я столкнулся с ситуацией, когда я не понимаю, почему они работают так, как они работают.

Я пытаюсь определить, может ли тип вызывать begin и end. Приведенный ниже код дает ожидаемые результаты, если я изменю foo, чтобы получить его параметр по значению или константную ссылку, но я не уверен, почему он не работает при использовании ссылки на rvalue, и мне было интересно, если кто-нибудь может сказать мне, почему .

#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);
}

1 Ответ

6 голосов
/ 15 апреля 2011

Это потому, что T выводится как ссылочный тип lvalue, когда foo вызывается с lvalue.Попробуйте:

has_begin_end<typename remove_reference<T>::type>::value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...