I have a C++ class Finder
that stores a location in containers plus some additional data. Such containers have the type std::string
but also char *
or MyString
. Say, the class looks like this (Iterator<TContainer>::Type
is a trait / metafunction that returns the iterator type for a given container):
template <typename TContainer>
class Finder
{
public:
typedef typename Iterator<TContainer>::Type TIterator;
TIterator iterator;
// Initialization of iterator: How to do it generically?
// Finder {} // problem with pointers!
// Finder() : iterator(0) {} // problem with iterators!
};
The main problem now is how to initialize the iterator that can be a pointer or an iterator. If I only wanted to support my own containers then I could simply implement a constructor that takes nullptr_t
following the nullptr idiom. However, since I want to support pointers, my own iterators and STL iterators, I'm a bit out of depth here.
The best thing that I can imagine is to write a getNil<>()
function, e.g. the code below. However, now at least three questions arise:
Is this the best way to achieve my aim?
How to determine whether a type is a STL iterator? I would probably need some #if
s, and tailor code to each compiler/STL version to use.
Is it possible at all to get a nil iterator in the STL? Is the result of x-y
in std::vector<int> x, y; int x = x-y;
defined at all?
The code:
// Forward declaration.
template <typename T>
T getNil<T>();
template <typename TValue> TValue * getNil<TValue *>()
{ return NULL; }
template <typename TValue> TValue * const getNil<TValue * const>()
{ return NULL; }
template <> TValue * const getNil<MyIterator>()
{ return MyIterator(nullptr); } // nullptr from above idiom
template <> TStlIterator
boost::enable_if<
MagicallyDetermineIfIsStlIterator<TStlIterator>::value,
TStlIterator>
getNil<TStlIterator>()
{ return MyIterator(nullptr); } // nullptr from above idiom
Finder() : iterator() { }
Should do the trick. Not providing an argument for a member in the initialization list will call the default constructor on a type that has one, and will zero-initialize POD types including pointers (and it will fail if the type has no default constructor, but that seems unlikely given your scenario).