Template overloading?

This is a discussion on Template overloading? within the C++ Programming forums, part of the General Programming Boards category; This is strange... VC++ gives me this error: error C2780: 'void StrUtils::ToUpper(std::basic_string<_Elem,_Traits, _Alloc> &,const std::locale &)' : expects 2 arguments ...

  1. #1
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545

    Template overloading?

    This is strange... VC++ gives me this error:
    error C2780: 'void StrUtils::ToUpper(std::basic_string<_Elem,_Traits, _Alloc> &,const std::locale &)' : expects 2 arguments - 4 provided
    if I try to overload my ToUpper() function template like this:
    Code:
    template <typename E>
    class ToUpperFunctor	:	public std::binary_function<E, std::locale, E>
    {
    public:
    	E operator()( E  ch, const std::locale&  loc = std::locale() ) const
    	{
    		return std::toupper( ch, loc );
    	}
    };
    
    template <typename E,
    	  typename InIt,
    	  typename OutIt>
    void ToUpper( InIt  start1,
    	      InIt  end1,
    	     OutIt  start2,
    	     const std::locale&  loc = std::locale() )
    {
    	std::transform( start1, end1,
    			start2,
    			std::bind2nd( ToUpperFunctor<E>(), loc ) );
    }
    
    template <typename E,
    	  typename T,
    	  typename A>
    void ToUpper( std::basic_string<E, T, A>&  str,
    		       const std::locale&  loc = std::locale() )
    {
    	typedef std::basic_string<E, T, A>::iterator	iter;
    	ToUpper( str.begin(), str.end(),
    		 str.begin(), loc );
    }
    but it compiles fine if I specify the template parameters:
    Code:
    template <typename E>
    class ToUpperFunctor	:	public std::binary_function<E, std::locale, E>
    {
    public:
    	E operator()( E  ch, const std::locale&  loc = std::locale() ) const
    	{
    		return std::toupper( ch, loc );
    	}
    };
    
    template <typename E,
    	  typename InIt,
    	  typename OutIt>
    void ToUpper( InIt  start1,
    	      InIt  end1,
    	     OutIt  start2,
    	     const std::locale&  loc = std::locale() )
    {
    	std::transform( start1, end1,
    			start2,
    			std::bind2nd( ToUpperFunctor<E>(), loc ) );
    }
    
    template <typename E,
    	  typename T,
    	  typename A>
    void ToUpper( std::basic_string<E, T, A>&  str,
    		       const std::locale&  loc = std::locale() )
    {
    	typedef std::basic_string<E, T, A>::iterator	iter;
    	ToUpper<E, iter, iter>( str.begin(), str.end(),
    				str.begin(), loc );
    }
    But both template functions take the same number of template parameters, so how could that possibly help, and why doesn't it know which function I'm talking about to begin with?

  2. #2
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I think I know why I need to explicitely specify the template parameters -- because the E parameter isn't used in the function parameter list. But I'm still at a loss as to why VC++ thinks I'm talking about the 2 parameter function instead of the 4 parameter one?

    If nobody has a good answer for that, then maybe this is easier -- Is there a way limit the types that can be used for template parameters? If I only want OutIt to be instantiated using an output iterator, is it possible to do that?

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It seems to me that you are over-complicating things.

    Here's something that should work the same with a lot less template parameters. I hope the way E is deduced (with iterator::value_type) is standard.

    Code:
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <cctype>
    
    template <typename E>
    class ToUpperFunctor	:	public std::binary_function<E, std::locale, E>
    {
    public:
    	E operator()( E  ch, const std::locale&  loc = std::locale() ) const
    	{
    		return std::toupper( ch, loc );
    	}
    };
    
    template <typename InIt, typename OutIt>
    void ToUpper( InIt  start1,
    	      InIt  end1,
    	     OutIt  start2,
    	     const std::locale&  loc = std::locale() )
    {
         typedef typename InIt::value_type E;
    	std::transform( start1, end1,
    			start2,
    			std::bind2nd( ToUpperFunctor<E>(), loc ) );
    }
    
    template <typename StringType>
    void ToUpper( StringType&  str,
    		       const std::locale&  loc = std::locale() )
    {
    	ToUpper( str.begin(), str.end(), str.begin(), loc );
    }
    
    int main()
    {
        std::string a = "Hello", b = "world";
        ToUpper(a);
        ToUpper(b.begin(), b.end(), b.begin());
        std::cout << a << " " << b << '\n'; //HELLO WORLD
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    typedef std::basic_string<E, T, A>::iterator iter;
    This is missing a typename and shouldn't compile in the first place. What version of VC++ is this?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,548
    6.0?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by CornedBee View Post
    This is missing a typename and shouldn't compile in the first place. What version of VC++ is this?
    That was VC++ 2005 express.
    I thought it needed a typename too, but when it compiled I thought maybe since only part of the name before the :: was a template that maybe it wasn't required...
    Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. template overloading question
    By plutino in forum C++ Programming
    Replies: 14
    Last Post: 02-27-2009, 01:10 AM
  2. Specialising a member function with a template template parameter
    By the4thamigo_uk in forum C++ Programming
    Replies: 10
    Last Post: 10-12-2007, 04:37 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 11:54 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21