I want to implement a range constructor for a specific object, but I want to limit it to only accepting two input iterators.
I tried to compile this code with gcc 7.1.0.
File test.cpp
#include <vector> #include <type_traits> #include <typeinfo> template <typename Iterator> using traits = typename std::iterator_traits<Iterator>::iterator_category; template <typename T> class A{ private: std::vector<T> v; public: template <typename InputIterator, typename = std::enable_if_t< typeid(traits<InputIterator>) == typeid(std::input_iterator_tag)> > A(InputIterator first, InputIterator last) : v(first, last) {} }; int main(){ std::vector<double> v = {1, 2, 3, 4, 5}; A<double> a(v.begin(), v.end()); }
I get this compilation error with g++ test.cpp -o test :
test.cpp: In function 'int main()': test.cpp:27:34: error: no matching function for call to 'A<double>::A(std::vector<double>::iterator, std::vector<double>::iterator)' A<double> a(v.begin(), v.end()); ^ test.cpp:22:7: note: candidate: template<class InputIterator, class> A<T>::A(InputIterator, InputIterator) A(InputIterator first, InputIterator last) : v(first, last) {} ^ test.cpp:22:7: note: template argument deduction/substitution failed: test.cpp: In substitution of 'template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type [with bool _Cond = ((const std::type_info*)(& _ZTISt26random_access_iterator_tag))->std::type_info::operator==(_ZTISt18input_iterator_tag); _Tp = void]': test.cpp:18:16: required from here test.cpp:19:49: error: call to non-constexpr function 'bool std::type_info::operator==(const std::type_info&) const' typeid(traits<InputIterator>) == test.cpp:18:16: note: in template argument for type 'bool' typename = std::enable_if_t< ^~~~~~~~ test.cpp:10:7: note: candidate: A<double>::A(const A<double>&) class A{ ^ test.cpp:10:7: note: candidate expects 1 argument, 2 provided test.cpp:10:7: note: candidate: A<double>::A(A<double>&&) test.cpp:10:7: note: candidate expects 1 argument, 2 provided
I decided to use the default template parameter, because it is more suitable for designers. Using the typeid() operator is that I find it very easy to read when executing the code, but I can't get it to work in any way.
Other solutions look very strange and really obscure (for example, so that the InputIterator parameter has certain methods, such as * it or ++ it). If I cannot do this, I would appreciate a more or less easy-to-read solution.