我正在尝试为使用双向迭代器的容器编写一个通用的反向包装器,使用std::reverse_iterator
.
但是,似乎当编译器查找begin(...)
orend(...)
时,它会说找不到匹配的函数调用,reverse_wrapper<CONTAINER>::begin(container)
因为候选者需要 0 个参数,但提供了 1 个参数。
我会猜到这是因为std::begin(myArray&)
并且std::end(myArray&)
不存在。强制他们进入std
命名空间是行不通的(无论如何也不可取)。我也尝试std::
从我的中删除前缀,reverse_wrapper
但这没有用,并且还会破坏工作std
容器的实现。
这似乎是一个范围解析问题,但我似乎无法得到修复。我究竟做错了什么?
代码:
#include <iterator>
#include <iostream>
#include <vector>
#define Fn1 0 // std container WORKS
#define Fn2 1 // non-std container DOESN'T WORK
template <typename Container>
struct reverse_wrapper
{
Container& container;
auto begin()
-> std::reverse_iterator< decltype(std::end(container)) >
{
return std::reverse_iterator< decltype(std::end(container)) >(std::end(container));
}
auto end()
-> std::reverse_iterator< decltype(std::begin(container)) >
{
return std::reverse_iterator< decltype(std::begin(container)) >(std::begin(container));
}
};
template <typename Container>
auto reverse(Container&& container)
-> reverse_wrapper<Container>
{
return{ container };
}
struct myArray
{
int elements[5] = {1,2,3,4,5};
};
int* begin(myArray& array) { return &array.elements[0]; }
int* end(myArray& array) { return &array.elements[5]; }
#if Fn1
void fn1()
{
std::vector<int> x = { 1,2,3,4,5 };
for (auto& ix : reverse(x))
{
std::cout << ix << std::endl;
}
std::cout << "-----" << std::endl;
for (auto& ix : x)
{
std::cout << ix << std::endl;
}
}
#endif
#if Fn2
void fn2()
{
myArray x;
for (auto& ix : reverse(x))
{
std::cout << ix << std::endl;
}
std::cout << "-----" << std::endl;
for (auto& ix : x)
{
std::cout << ix << std::endl;
}
}
#endif
int main()
{
#if Fn1
fn1();
#endif
#if Fn2
fn2();
#endif
}
错误:
在“struct reverse_wrapper”的实例化中: 61:30:从这里需要 14:56:错误:没有匹配函数调用“end(myArray&)” 14:56:注:候选人为: 在 /usr/include/c++/4.9/string:51:0 包含的文件中, 来自 /usr/include/c++/4.9/bits/locale_classes.h:40, 来自 /usr/include/c++/4.9/bits/ios_base.h:41, 来自/usr/include/c++/4.9/ios:42, 来自/usr/include/c++/4.9/ostream:38, 来自 /usr/include/c++/4.9/iterator:64, 从1: /usr/include/c++/4.9/bits/range_access.h:68:5: 注意:模板 decltype (__cont.end()) std::end(_Container&) end(_Container& __cont) -> decltype(__cont.end()) ^ /usr/include/c++/4.9/bits/range_access.h:68:5: 注意:模板参数推导/替换失败: /usr/include/c++/4.9/bits/range_access.h:代替'template decltype (__cont.end()) std::end(_Container&) [with _Container = myArray]': 14:56:'struct reverse_wrapper' 需要 61:30:从这里需要 /usr/include/c++/4.9/bits/range_access.h:68:5: 错误:“struct myArray”没有名为“end”的成员 在“struct reverse_wrapper”的实例化中: 61:30:从这里需要 /usr/include/c++/4.9/bits/range_access.h:78:5: 注意:模板 decltype (__cont.end()) std::end(const _Container&) end(const _Container& __cont) -> decltype(__cont.end()) ^ /usr/include/c++/4.9/bits/range_access.h:78:5:注意:模板参数推导/替换失败: /usr/include/c++/4.9/bits/range_access.h:代替'template decltype (__cont.end()) std::end(const _Container&) [with _Container = myArray]': 14:56:'struct reverse_wrapper' 需要 61:30:从这里需要 /usr/include/c++/4.9/bits/range_access.h:78:5:错误:“const struct myArray”没有名为“end”的成员 在“struct reverse_wrapper”的实例化中: 61:30:从这里需要 /usr/include/c++/4.9/bits/range_access.h:97:5: 注意:模板 _Tp* std::end(_Tp (&)[_Nm]) 结束(_Tp (&__arr)[_Nm]) ^ /usr/include/c++/4.9/bits/range_access.h:97:5:注意:模板参数推导/替换失败: 14:56:注意:不匹配的类型 '_Tp [_Nm]' 和 'myArray' 在 /usr/include/c++/4.9/bits/basic_string.h:42:0 包含的文件中, 来自 /usr/include/c++/4.9/string:52, 来自 /usr/include/c++/4.9/bits/locale_classes.h:40, 来自 /usr/include/c++/4.9/bits/ios_base.h:41, 来自/usr/include/c++/4.9/ios:42, 来自/usr/include/c++/4.9/ostream:38, 来自 /usr/include/c++/4.9/iterator:64, 从1: /usr/include/c++/4.9/initializer_list:99:5: 注意:模板 constexpr const _Tp* std::end(std::initializer_list) end(initializer_list __ils) noexcept ^ /usr/include/c++/4.9/initializer_list:99:5:注意:模板参数推导/替换失败: 14:56:注意:“myArray”不是从“std::initializer_list”派生的 20:58:错误:没有匹配函数调用“begin(myArray&)” 20:58:注:候选人是: 在 /usr/include/c++/4.9/string:51:0 包含的文件中, 来自 /usr/include/c++/4.9/bits/locale_classes.h:40, 来自 /usr/include/c++/4.9/bits/ios_base.h:41, 来自/usr/include/c++/4.9/ios:42, 来自/usr/include/c++/4.9/ostream:38, 来自 /usr/include/c++/4.9/iterator:64, 从1: /usr/include/c++/4.9/bits/range_access.h:48:5: 注意:模板 decltype (__cont.begin()) std::begin(_Container&) 开始(_Container& __cont) -> decltype(__cont.begin()) ^ /usr/include/c++/4.9/bits/range_access.h:48:5:注意:模板参数推导/替换失败: /usr/include/c++/4.9/bits/range_access.h:代替'template decltype (__cont.begin()) std::begin(_Container&) [with _Container = myArray]': 20:58:从“struct reverse_wrapper”中需要 61:30:从这里需要 /usr/include/c++/4.9/bits/range_access.h:48:5: 错误:“struct myArray”没有名为“begin”的成员 在“struct reverse_wrapper”的实例化中: 61:30:从这里需要 /usr/include/c++/4.9/bits/range_access.h:58:5: 注意:模板 decltype (__cont.begin()) std::begin(const _Container&) 开始(const _Container& __cont) -> decltype(__cont.begin()) ^ /usr/include/c++/4.9/bits/range_access.h:58:5:注意:模板参数推导/替换失败: /usr/include/c++/4.9/bits/range_access.h:代替'template decltype (__cont.begin()) std::begin(const _Container&) [with _Container = myArray]': 20:58:从“struct reverse_wrapper”中需要 61:30:从这里需要 /usr/include/c++/4.9/bits/range_access.h:58:5:错误:“const struct myArray”没有名为“begin”的成员 在“struct reverse_wrapper”的实例化中: 61:30:从这里需要 /usr/include/c++/4.9/bits/range_access.h:87:5: 注意:模板 _Tp* std::begin(_Tp (&)[_Nm]) 开始(_Tp (&__arr)[_Nm]) ^ /usr/include/c++/4.9/bits/range_access.h:87:5:注意:模板参数推导/替换失败: 20:58:注意:不匹配的类型 '_Tp [_Nm]' 和 'myArray' 在 /usr/include/c++/4.9/bits/basic_string.h:42:0 包含的文件中, 来自 /usr/include/c++/4.9/string:52, 来自 /usr/include/c++/4.9/bits/locale_classes.h:40, 来自 /usr/include/c++/4.9/bits/ios_base.h:41, 来自/usr/include/c++/4.9/ios:42, 来自/usr/include/c++/4.9/ostream:38, 来自 /usr/include/c++/4.9/iterator:64, 从1: /usr/include/c++/4.9/initializer_list:89:5: 注意:模板 constexpr const _Tp* std::begin(std::initializer_list) begin(initializer_list __ils) noexcept ^ /usr/include/c++/4.9/initializer_list:89:5:注意:模板参数推导/替换失败: 20:58:注意:“myArray”不是从“std::initializer_list”派生的 在函数 'void fn2()' 中: 61:30:错误:从“reverse_wrapper”类型的表达式中对“myArray&”类型的引用进行无效初始化 38:6:注意:传递 'int* begin(myArray&)' 的参数 1 61:30:错误:从“reverse_wrapper”类型的表达式中对“myArray&”类型的引用进行无效初始化 39:8:注意:传递 'int* end(myArray&)' 的参数 1