472,782 Members | 1,152 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,782 software developers and data experts.

partial ordering of template functions & parameter specification

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;
}
-- cut --
May 13 '06 #1
9 2678

Marek Vondrak wrote:
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;
}
-- cut --


Based on reading the relevant section from Vandervoorde/Josuttis book,
the second assign function would be more specialized than the first
function and therefore, when explicity providing parameters, the second
one is selected.

May 13 '06 #2

<am******@gmail.com> píse v diskusním príspevku
news:11**********************@d71g2000cwd.googlegr oups.com...

Marek Vondrak wrote:
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; // [1]
std::cout << assign( m, Plus<M, M>(), O() ) << std::endl; // [2]
}
-- cut --


Based on reading the relevant section from Vandervoorde/Josuttis book,
the second assign function would be more specialized than the first
function and therefore, when explicity providing parameters, the second
one is selected.


This is what I would intuitively expect to happen but both G++ and MSVC
behave just opposite. If template parameters are specified explicitly, the
first assign function is called at [1] despite the fact that the second
assign function is more specialized. If template parameters are not
specified and are deduced by the compiler ([2]), the more specialized
function is called as expected.

Can anyone explain why is this happening?

-- Marek
May 13 '06 #3
> This is what I would intuitively expect to happen but both G++ and MSVC
behave just opposite.


Sorry, I did not read the follow up properly. Correction: I would expect the
program to print "2" "2" (the specialized assign should be called in both
the cases, regardless of whether template parameters are specified or not).
-- Marek
May 13 '06 #4
Marek Vondrak wrote:
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() ) <<
Well this surely cannot use the template with one parameter since you
are specifying three of them. That must print 1.
std::cout << assign( m, Plus<M, M>(), O() ) << std::endl;
This will prefer the template with one parameter. The compiler will
always select the most specialized template if it has a choice. This
must print 2.
}

Jonathan

May 13 '06 #5

Marek Vondrak wrote:
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. 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.

May 13 '06 #6
>> 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
May 14 '06 #7

Marek Vondrak wrote:
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.


I repeat. There is no *partial* specialization for function templates.
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.


AS2 is a *full* function template specialization because it has no
template arguments.
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:


Your belief is premised on a false assumption that there exists partial
function template specialization.

May 14 '06 #8
> I repeat. There is no *partial* specialization for function templates.
Your belief is premised on a false assumption that there exists partial
function template specialization.


Okay, thanks Maxim and sorry for my doubts. I thought partial specialization
for function templates was supported. That is why I originally asked whether
the second assign() was actually a *specialization* or an *overload* of the
first assign. I also asked in comp.lang.c++.moderated and was luckily
provided with links to relevant articles. Now, it should be clear. Thanks
for help.

-- Marek
May 15 '06 #9
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:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

May 15 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: claude uq | last post by:
Hello, Am trying to use template functions within some class to convert int, float, doubles, etc into strings. Below, three ways to do it via use of "to_string(const T & Value)" . The only...
2
by: Frank Schmitt | last post by:
Hi! Suppose I have a class template Foo with a member function template bar - so far so good: template <typename T> struct Foo { template <typename U> void bar(const U& u); };
4
by: richardclay09 | last post by:
Hi Can someone please write some "compare and contrast" notes for "Template functions vs. function objects"? When to use one and not the other? For example, the TF square_f does the same thing as...
3
by: REH | last post by:
I need to create template functions with the same name but different number of template parameters. My compiler says this is illegal: template<class TO, class F1> TO convert_to(); ...
5
by: Andrei Tarassov | last post by:
Hi! I would like to know if it is possible to implement something like this: template <class X, class Y> X void func(X, Y) { ... } template <class X, class Y> Y void func(X, Y) { ... }
1
by: shuisheng | last post by:
Dear All, I am confused about the template functions in template class. Such as I have template class A <class T, int n> In side the class, I have function A<T,nfun() and
2
by: newbie | last post by:
I happened to read boost library code and realized that most (the part I read) functions are inlined like: template <class Key> inline void Foo(const Key& k) { ... ... } Is there a strong...
2
by: vectorizor | last post by:
Hello all, I am attempting to vectorize few template functions with the Intel compiler, but without much success so far. Ok granted, this question is not 100% c++, but it is related enough that...
4
by: Olaf | last post by:
Hi, I'm writing a small wrapper for libcurl. For Options I use: template<typename T, long CURLOPT_ID> class CurlOption: boost::noncopyable { public: typedef typename...
0
by: Rina0 | last post by:
Cybersecurity engineering is a specialized field that focuses on the design, development, and implementation of systems, processes, and technologies that protect against cyber threats and...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.