4
我最近开始使用右值引用,我遇到了一个情况,我不明白他们为什么以他们的方式工作。Rvalue引用和SFINAE
我试图确定一个类型是否可以调用begin
和end
。下面的代码给出了预期的结果,如果我通过值或const引用更改foo
来接受它的参数,但我不确定为什么它在使用右值引用时不起作用,我想知道是否有人能告诉我为什么。
#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);
}
而不是'*((U *)0)',使用'std :: declval ()'。 – GManNickG 2011-04-15 18:38:24
谢谢GMan。看起来我在阅读新的C++ 0x功能时忽略了declval。 – Adam 2011-04-15 18:55:15