partial ordering of overloaded function templates

Discussion in 'C++' started by John Harrison, Jun 8, 2004.

  1. I've tried the following program on two different compilers (VC++ 7.1 and
    gcc 3.3.1) and both print "first" when I expected "second". Why is that?

    #include <vector>
    #include <iostream>

    template <class Iter>
    void func(Iter i)
    {
    std::cout << "first\n";
    }

    template <class T>
    void func(typename std::vector<T>::iterator i)
    {
    std::cout << "second\n";
    }

    int main()
    {
    std::vector<int> v;
    func(v.begin());
    }

    john
     
    John Harrison, Jun 8, 2004
    #1
    1. Advertising

  2. "John Harrison" <> wrote in message
    news:...
    > I've tried the following program on two different compilers (VC++ 7.1 and
    > gcc 3.3.1) and both print "first" when I expected "second". Why is that?
    >


    > template <class T>
    > void func(typename std::vector<T>::iterator i)


    OK, I've figured it out, 'std::vector<T>::iterator' is a non-deduced
    context. Annoying.

    john
     
    John Harrison, Jun 8, 2004
    #2
    1. Advertising

  3. John Harrison wrote in news: in comp.lang.c++:

    > I've tried the following program on two different compilers (VC++ 7.1 and
    > gcc 3.3.1) and both print "first" when I expected "second". Why is that?
    >


    Because the second is non-deducable.

    Its non-deducable because the standard says so.

    > template <class T>
    > void func(typename std::vector<T>::iterator i)
    > {
    > std::cout << "second\n";
    > }
    >


    The good news is: its non-deducable :), which can be exploited:

    news:<>

    If the news link doesn't work: http://tinyurl.com/2smov

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Jun 8, 2004
    #3
  4. John Harrison wrote:
    > I've tried the following program on two different compilers (VC++ 7.1 and
    > gcc 3.3.1) and both print "first" when I expected "second". Why is that?
    >
    > #include <vector>
    > #include <iostream>
    >
    > template <class Iter>
    > void func(Iter i)
    > {
    > std::cout << "first\n";
    > }
    >
    > template <class T>
    > void func(typename std::vector<T>::iterator i)
    > {
    > std::cout << "second\n";
    > }
    >
    > int main()
    > {
    > std::vector<int> v;
    > func(v.begin());
    > }


    Function member type resolution you're looking for is not allowed
    (because in many cases it is ambiguous).

    You *might* be able to do somthing like the example below. This may not
    compile on all compilers. I recently found a number of bugs in gcc and
    VC++ in this area (Comeau got it right - again!). gcc 3.4.0 appears to
    compile this fine.


    #include <vector>
    #include <list>
    #include <iostream>


    template <bool v>
    struct Helper
    {
    };

    template <typename T1, typename T2>
    struct IsSameType
    {
    static const bool value = false;
    };

    template <typename T>
    struct IsSameType<T, T>
    {
    static const bool value = true;
    };


    template <class T>
    void func(
    const T & v,
    Helper<
    IsSameType<
    T,
    typename std::vector<typename T::value_type>::iterator
    >::value
    > * x

    )
    {
    std::cout << "second\n";
    }

    struct Y
    {
    };

    template <class Iter>
    struct X
    : Y
    {
    };

    template <class Iter>
    void func(Iter i, ... )
    {
    std::cout << "first\n";
    }

    int main()
    {
    std::vector<int> v;
    func(v.begin(), static_cast< Helper<true> * >( 0 ) );
    std::list<int> x;
    func(x.begin(), static_cast< Helper<true> * >( 0 ) );
    }
     
    Gianni Mariani, Jun 8, 2004
    #4
  5. In article <>,
    "John Harrison" <> wrote:

    > "John Harrison" <> wrote in message
    > news:...
    > > I've tried the following program on two different compilers (VC++ 7.1 and
    > > gcc 3.3.1) and both print "first" when I expected "second". Why is that?
    > >

    >
    > > template <class T>
    > > void func(typename std::vector<T>::iterator i)

    >
    > OK, I've figured it out, 'std::vector<T>::iterator' is a non-deduced
    > context. Annoying.
    >
    > john


    Here is something that you can try, works with Metrowerks:

    #include <vector>
    #include <iostream>

    template <class Iter>
    typename Metrowerks::restrict_to
    <
    !Metrowerks::is_same
    <
    Iter,
    typename std::vector<typename
    std::iterator_traits<Iter>::value_type>::iterator
    >::value,

    void
    >::type

    func(Iter i)
    {
    std::cout << "first\n";
    return (void)0;
    }

    template <class Iter>
    typename Metrowerks::restrict_to
    <
    Metrowerks::is_same
    <
    Iter,
    typename std::vector<typename
    std::iterator_traits<Iter>::value_type>::iterator
    >::value,

    void
    >::type

    func(Iter i)
    {
    std::cout << "second\n";
    return (void)0;
    }

    int main()
    {
    std::vector<int> v;
    func(v.begin());
    }

    Metrowerks::restrict_to is the same things as boost::enable_if (
    http://www.boost.org/libs/utility/enable_if.html ).

    -Howard
     
    Howard Hinnant, Jun 8, 2004
    #5
  6. "John Harrison" <> wrote in message
    news:...
    > I've tried the following program on two different compilers (VC++ 7.1 and
    > gcc 3.3.1) and both print "first" when I expected "second". Why is that?
    >
    > #include <vector>
    > #include <iostream>
    >
    > template <class Iter>
    > void func(Iter i)
    > {
    > std::cout << "first\n";
    > }
    >
    > template <class T>
    > void func(typename std::vector<T>::iterator i)
    > {
    > std::cout << "second\n";
    > }
    >
    > int main()
    > {
    > std::vector<int> v;
    > func(v.begin());
    > }
    >
    > john
    >


    Thanks for the suggested workarounds. Unfortunately the code I posted bears
    little relation to my real code so they aren't applicable, interesting
    though. Fortunately though once I realised what the problem was I had a
    different way to solve this.

    john
     
    John Harrison, Jun 9, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop
    Replies:
    3
    Views:
    479
  2. Marek Vondrak
    Replies:
    9
    Views:
    332
    Marek Vondrak
    May 15, 2006
  3. recover
    Replies:
    2
    Views:
    812
    recover
    Jul 25, 2006
  4. nbigaouette

    Z-Ordering (Morton ordering) question

    nbigaouette, Nov 5, 2009, in forum: C Programming
    Replies:
    2
    Views:
    2,170
  5. Rodolfo Lima
    Replies:
    4
    Views:
    398
    Paul Bibbings
    Jul 26, 2010
Loading...

Share This Page