我可以获得“迭代器”吗?对于模板类型,无论该类型是数组还是类似 STL 的容器?

发布于 2025-01-08 08:34:08 字数 427 浏览 2 评论 0原文

这是我的例子:

template<typename TContainer>
class MyClass
{
public:
   typedef typename SomeUnknownHelper<TContainer>::iterator iterator;
};

std::vector<int>::iterator i = MyClass<std::vector<int>>::iterator;
int *pi = MyClass<int[20]>::iterator;

基本上,我不知道如何编写SomeUnknownHelper

我知道我可以专门化 MyClass 本身,但在我的实际情况中,这会很麻烦,因为类很大。

Here's my example:

template<typename TContainer>
class MyClass
{
public:
   typedef typename SomeUnknownHelper<TContainer>::iterator iterator;
};

std::vector<int>::iterator i = MyClass<std::vector<int>>::iterator;
int *pi = MyClass<int[20]>::iterator;

Basically, I don't know how to write SomeUnknownHelper.

I know I could specialize MyClass itself, but in my real-world case it would be a hassle because the class is large.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不甘平庸 2025-01-15 08:34:08

使用 decltypestd::begin 可以轻松实现这一点:

#include <iterator>
#include <utility>

namespace tricks{
  using std::begin; // fallback for ADL
  template<class C>
  auto adl_begin(C& c) -> decltype(begin(c)); // undefined, not needed
  template<class C>
  auto adl_begin(C const& c) -> decltype(begin(c)); // undefined, not needed
}

template<typename TContainer>
class MyClass
{
public:
   typedef decltype(tricks::adl_begin(std::declval<TContainer>())) iterator;
};

std::vector<int>::iterator i = MyClass<std::vector<int>>::iterator;
int *pi = MyClass<int[20]>::iterator;

更好的选择可能是使用 Boost.Range:

#include <boost/range/metafunctions.hpp>

template<typename TContainer>
class MyClass
{
public:
   typedef typename boost::range_iterator<TContainer>::type iterator;
};

std::vector<int>::iterator i = MyClass<std::vector<int>>::iterator;
int *pi = MyClass<int[20]>::iterator;

That's easily doable with decltype and std::begin:

#include <iterator>
#include <utility>

namespace tricks{
  using std::begin; // fallback for ADL
  template<class C>
  auto adl_begin(C& c) -> decltype(begin(c)); // undefined, not needed
  template<class C>
  auto adl_begin(C const& c) -> decltype(begin(c)); // undefined, not needed
}

template<typename TContainer>
class MyClass
{
public:
   typedef decltype(tricks::adl_begin(std::declval<TContainer>())) iterator;
};

std::vector<int>::iterator i = MyClass<std::vector<int>>::iterator;
int *pi = MyClass<int[20]>::iterator;

An even better option might be using Boost.Range:

#include <boost/range/metafunctions.hpp>

template<typename TContainer>
class MyClass
{
public:
   typedef typename boost::range_iterator<TContainer>::type iterator;
};

std::vector<int>::iterator i = MyClass<std::vector<int>>::iterator;
int *pi = MyClass<int[20]>::iterator;
比忠 2025-01-15 08:34:08

这只是一个专业,那能有多糟糕?

template <typename T> struct ContainerTrait
{
    typedef typename T::iterator iterator;
    typedef typename T::const_iterator const_iterator;
};

template <typename T, unsigned int N> struct ContainerTrait<T[N]>
{
    typedef T * iterator;
    typedef T const * const_iterator;
};

或者,您可以使用免费的 std::begin/std::endauto

auto it = std::begin(x);  // x could be vector<int> or float[10]...

That's only one single specialization, how bad could that be?

template <typename T> struct ContainerTrait
{
    typedef typename T::iterator iterator;
    typedef typename T::const_iterator const_iterator;
};

template <typename T, unsigned int N> struct ContainerTrait<T[N]>
{
    typedef T * iterator;
    typedef T const * const_iterator;
};

Alternatively, you can use the free std::begin/std::end and auto:

auto it = std::begin(x);  // x could be vector<int> or float[10]...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文