Re: Terminology in english :)
On Mar 18, 1:45 am, Taras_96 <taras...@gmail.com> wrote:
On Mar 18, 5:28 am, James Kanze <james.ka...@gmail.com> wrote:
On 17 mar, 16:38, Taras_96 <taras...@gmail.com> wrote:
Thanks Andrey, James, and Victor for your excellent responses.
So, if I understand correctly:
1) Overload resolution can be done by the compiler where the function
is called
2) Since transform is templated, it is overloaded (and it also has a C=
version)
Not quite (and it certainly doesn't have a C version). Since
transform is a function template, it doesn't exist as a function
until the compiler has worked out what arguments to use. In
theory, you could specify them explicitly, e.g.
std::transform< ... >( ... ) ;
In practice, you're not going to want to. (The first template
argument is something like std::basic_string< char,
std::char_traits< char >, std::allocator >::iterator. And the
others aren't any simpler.) You'll want compiler to do
automatic type deduction. But the compiler can't do that until
it knows that type it has to deduce from.
My statement may have made more sense if I used the correct function
name - toupper! Somehow I made this mistake.
A yes. So there's both a function template and overloading for
the compiler to contend with.
On Mar 18, 5:28 am, James Kanze <james.ka...@gmail.com> wrote:
On 17 mar, 16:38, Taras_96 <taras...@gmail.com> wrote:
4) By using functors we can accomplish delaying the overload
resolution until the function is actually called within the transform
function, similar to 1).
That's not really the difference. In this case, you're
arranging for the type of the unary_function to be a
non-template class type. No template, and the compiler knows
the exact type.
And by arranging it to be a non-template class type, we delay
overload resolution until the function is called?
Overload resolution always occurs at the call site. The problem
here isn't overload resolution---it's template type deduction.
If the fourth argument is an overload set which contains a
function template, the compiler cannot do type deduction---it
needs to know the target type to do type deduction on the
function template, and it needs the exact type of the function
in order to do type deduction for std::transform. There's a
cyclic dependency. If the fourth argument is an overloaded
function, even without a template, the compiler still needs to
know the target type to do overload resolution, and it needs the
results of the overload resolution to do argument deduction for
std::transform (and thus determine the target type).
When we pass a functional object, we specify an exact type---the
type of the object. This breaks the cycle in the dependencies:
the type of the argument is fixed; the compiler does not have to
deduce or resolve it. This is true regardless of whether the
functional argument is a template or not---it is an object, it
has a fixed type, and there is no possible overloading or
automatic type deduction. There is no automatic type deduction
for class templates or objects. Only for functions. Thus, for
example, if I create a ToUpper template class:
template< typename charT >
class ToUpper
{
public:
explicit ToUpper( std::locale const& l = std::locale() )
: myLocale( l )
, myCtype( &std::use_locale< std::ctype< charT >
( l ) )
{
}
charT operator()( charT ch ) const
{
return myCtype->toupper( ch ) ;
}
private:
std::locale myLocale ;
std::ctype< charT > const*
myCtype ;
} ;
I would have to explicitly specify the type in order to use it:
std::transform( s.begin(), s.end(), s.begin(),
ToUpper< char >() ) ;
And having explicitly specified the type, the compiler no longer
has any argument deduction or overload resolution to do, and the
cycle is broken.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34