I am trying to create constructors for building a class, that can take iterators of anytype, as long as they are an iterator for a specific value_type
. With a different handler for all iterators of another value_type
.
Doing it for one works with common awful template error messages if you use the wrong value_type
.
But I cannot figure out how to provide support for a constructor using templates of the second valuetype.
class SomeDataStorageClass
{
public:
template<class InputIt>
SomeDataStorageClass(InputIt begin, InputIt end)
{
//Do some magic stuff with the iterators, making assumptions about the value type stored inside...
}
};
If I was using C++20 I could use if constexpr
but I am stuck using C++14.
You can use tag-dispatching and delegating constructors. The second constructor is for any value type while the third is for a specific type. You can add as many as you like. Replace SpecificValueType
with the actual type you want to dispatch for.
template<class T>
struct tag_t {};
class SomeDataStorageClass
{
public:
template<class InputIt>
SomeDataStorageClass(InputIt begin, InputIt end)
: SomeDataStorageClass(begin, end, tag_t<typename InputIt::value_type>{}) { }
template<class InputIt, class V>
SomeDataStorageClass(InputIt begin, InputIt end, tag_t<V>);
template<class InputIt>
SomeDataStorageClass(InputIt begin, InputIt end, tag_t<SpecificValueType>);
};
You can make this change to include array types:
template<class InputIt>
SomeDataStorageClass(InputIt begin, InputIt end)
: SomeDataStorageClass(begin, end, tag_t<std::decay_t<decltype(*begin)>>{}) { }