Topic: partial ordering of template functions & parameter specification
Author: Marek Vondrak <none@none.com>
Date: Mon, 15 May 2006 09:45:08 -0500 Raw View
>> Hello.
>>
>> I have written the following program and am curious why it prints "1"
>> "2".
>> What are the exact effects of explicitly providing function template
>> parameters at the call? Is the second assign() function really a
>> specialization of the first assign() or is it an assign() overload?
>>
>> Thank you.
>> -- Marek
>>
>> -- cut --
>> #include <iostream>
>>
>> class O { };
>> class M { };
>>
>> template <class Left, class Right>
>> class Plus { };
>>
>> template <class Left, class Right, class Op>
>> int assign( Left & left, const Right & right, const Op & op )
>> {
>> return 1;
>> }
>>
>> template <class Op>
>> int assign( M & left, const Plus<M, M> & right, const Op & op )
>> {
>> return 2;
>> }
>>
>> int main()
>> {
>> M m;
>>
>> std::cout << assign<M, Plus<M, M>, O>( m, Plus<M, M>(), O() ) <<
>> std::endl;
>> std::cout << assign( m, Plus<M, M>(), O() ) << std::endl;
>> }
>
> assign function templates are disparate function templates. There is no
> partial template specialization for functions.
Really? I think this was true in the prestandard era. Since C++98 there is a
partial specialization of functions and partional ordering rules.
> The first function
> template has three template arguments and the second has one. Therefore
> the second function template can not be used with three template
> arguments specified as you do.
Although I see the rationale behind your explanation, please consider the
following program.
class O { };
class M { };
template <class Left, class Right>
class Plus { };
// AS1
template <class Left, class Right, class Op>
void assign( Left & left, const Right & right, const Op & op ) { } //
Primary template
// AS2
template <>
void assign( M & left, const Plus<M, M> & right, const O & op ) { } //
Explicit specialization of AS1
int main()
{
M m;
assign<M, Plus<M, M>, O>( m, Plus<M, M>(), O() ); // Calls AS2
}
Why does it call AS2? It occurs to me, that AS1 is treated as the primary
template and AS2 as its explicit specialization. In the same sense I would
then believe that in the original program the first assign is the primary
template and the second assign its partial specialization:
template <class Left, class Right>
class Plus { };
// AS1
template <class Left, class Right, class Op>
void assign( Left & left, const Right & right, const Op & op ) { } //
Primary template again.
// AS2
template <class Op>
void assign( M & left, const Plus<M, M> & right, const Op & op ) { } //
Should be partial specialization of AS1?
int main()
{
M m;
assign<M, Plus<M, M>, O>( m, Plus<M, M>(), O() ); // Calls AS1! Why?
This is inconsistent with the explicit specialization example!
}
-- Marek
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]