を使用して双方向イテレータを使用するコンテナ用の汎用リバース ラッパーを作成しようとしていますstd::reverse_iterator
。
ただし、コンパイラがbegin(...)
orを検索すると、候補が 0 の引数を期待しているのに 1 が提供されているためend(...)
、一致する関数呼び出しが見つからないと言うようです。reverse_wrapper<CONTAINER>::begin(container)
これは存在しないためだ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]) end(_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&) begin(_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&) begin(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]) begin(_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 を渡す際に