   [C++] SFINAE
  I don't understand why this code doesn't compile. The error is with std::iterator_traits. Compiler says it can't find iterator_category for std::vector which is fine. Therfore the second template should be excluded from matching. Somehow, it casues an error. Any ideas?Don't write that it's not useful. I know it. I'm only testing.#include <vector>#include <algorithm>#include <iterator>template <typename Cont, typename Cont2>typename Cont2::iterator copy(const Cont& c, Cont2& dest){    //return std::copy(c.begin(), c.end(), std::back_inserter(dest));    std::copy(c.begin(), c.end(), std::back_inserter(dest));    return dest.end();}template <typename Cont, typename It>It copy(const Cont& c, It dest, typename std::iterator_traits<It>::pointer = 0){    return std::copy(c.begin(), c.end(), dest);}int main(){    std::vector<int> a, b;    copy(a, b);}Comeau errors:"stl_iterator_base.h", line 110: error: class"std::vector<int, std::allocator<int>>" has no member"iterator_category"    typedef typename _Iterator::iterator_category iterator_category;  ^detected during instantiation of class"std::iterator_traits<_Iterator> [with_Iterator=std::vector<int, std::allocator<int>>]" at line21 of "ComeauTest.c""ComeauTest.c", line 21: error: more than one instance of overloaded function "copy"matches the argument list, the choices that match are:  function template "Cont2::iterator copy(const Cont &, Cont2 &)"  function template "It copy(const Cont &, It,  std::iterator_traits<_ForwardIter2>::pointer)"  The argument types that you used are: (std::vector<int, std::allocator<int>>,  std::vector<int, std::allocator<int>>) copy(a, b); ^[Edited by - rozz666 on May 29, 2009 7:11:36 AM]
  *bump*;  *bump*   ;  I get similar error messages from VC++, but I think they may be red herrings and the real culprit may be:line 21error C2668: 'copy' : ambiguous call to overloaded functionAdditionally, neither function is a viable candidate for instantiationtemplate <typename Cont, typename Cont2>typename Cont2::iterator copy(const Cont& c, Cont2& dest){    return std::copy(c.begin(), c.end(), std::back_inserter(dest));}causeserror C2664: 'std::_Vector_iterator<_Ty,_Alloc>::_Vector_iterator(const std::_Vector_iterator<_Ty,_Alloc> &)' : cannot convert parameter 1 from 'std::back_insert_iterator<_Container>' to 'const std::_Vector_iterator<_Ty,_Alloc> &'whiletemplate <typename Cont, typename It>It copy(const Cont& c, It dest, typename std::iterator_traits<It>::pointer = 0){    return std::copy(c.begin(), c.end(), dest);}causeserror C2039: 'iterator_category' : is not a member of 'std::vector<_Ty>'HTHA5   ;  I fixed the error. Nevertheless, the first function is a viable candidate.   ;  The problem seems to be that you are not just checking whether It has a subtype pointer, but trying to instantiate the iterator_traits template which fails because vector doesn't have iterator_category typedef. I don't know if that should be covered by SFINAE.A solution might be to check for a type that is typedeffed in iterator types directly, and provide a third overload for pointers.#include <iostream>#include <vector>#include <algorithm>#include <iterator>template <typename Cont, typename Cont2>typename Cont2::iterator copy(const Cont& c, Cont2& dest){    std::cout << "Container\n";    std::copy(c.begin(), c.end(), std::back_inserter(dest));    return dest.end();}template <typename Cont, typename It>It copy(const Cont& c, It dest, typename It::iterator_category* = 0){    std::cout << "Iterator\n";    return std::copy(c.begin(), c.end(), dest);}template <typename Cont, typename Pointer>Pointer* copy(const Cont& c, Pointer* p){    std::cout << "Pointer\n";    return std::copy(c.begin(), c.end(), p);}int main(){    std::vector<int> a, b;    std::vector<int>::iterator it;    int* p;    copy(a, b);    copy(a, it);    copy(a, p);}(Or you could just rename one of the overloads - e.g the first might be called append instead - otherwise, if you indeed wanted to copy, you could use vector assignment operator. What kind of a system would it be where you don't know whether you'll end up with an iterator or a container where it would be important for them to be callable in the same way?)   ;Quote:Original post by rozz666*bump*Please do not bump posts in this forum.Thanks! [smile]   ;Quote:Original post by ApochPiQQuote:Original post by rozz666*bump*Please do not bump posts in this forum.Thanks! [smile]I am not a big friend of bumping (that is, when the bump frequency is higher than 1 bump in 3 days), too, but I think I have the slight memory of another moderator "allowing" it.Evil Steve, if you hear me, it was not by accident you? Otherwise, all my apologies :|I fail to find the relevant post right now, though.   ;  You may not have noticed but ApochPiQ is now the moderator for General Programming. He is now the guy who determines policy here.   ;  @phrensel:  Help Wanted allows bumping once every 24 hours.  In comparison, bumping once every 1-2 hours here is entirely inappropriate.  It's still in the most recent 5-10 threads at that point.  The idea behind bumping is to get things visible in the forum once more, and even then, expanding on your question is almost always much preferred -- if you're bumping, presumably there's a reason people aren't answering your question, right?   