c++templatesc++14enable-if

Template iterators of a specific value type


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.


Solution

  • 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)>>{}) { }