这是我的例子:
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
本身,但在我的实际案例中,这将是一个麻烦,因为班级很大。
答案 0 :(得分:2)
decltype
和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;
更好的选择可能是使用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;
答案 1 :(得分:1)
这只是一个单一的专业化,这有多糟糕?
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::end
和auto
:
auto it = std::begin(x); // x could be vector<int> or float[10]...