can a compiler figure out the correct type?

will the program work as expected on all compilers when I write something similar to:

template<typename T>
struct A
{
typedef T::C My;
CString ToString() {return typeid(My);}
};

struct S
{
}

struct M
{
typedef S C;
};

struct D
{
typedef S C;
};

template<class T>
A<T> function(T::C)
{
cout<<typeid(T);
return A<T>();
}

A<D> function(D::C)
{
cout<<"gotcha!";
return A<D>();
}

int main(...)
{
A<D> out(function<D>(S()));
cout<<out.ToString();
}


and what when I don't give the template-parameter and just write "function(S())"?
Last edited on
No, if it is written very much the same as that - not on any compiler.
Starter for 10:

1
2
3
4
5
6
template<typename T>
struct A
{
    typename typedef T::C My; //Need typename keyword here - because this is a dpendent name
CString ToString() {return typeid(My);}
};


And so on...

By the way the two functions called function are not proper overloads - they are the same.


and what when I don't give the template-parameter and just write "function(S())"?

You can't just write function(S()) because the compiler will not beable to deduce the template parameter
Last edited on
well, I tried it out with vc10 and what I get is that with the template-parameter the compiler is using the templated function, without it the compiler is using the other function which outputs gotcha. so obviously they are not the same. what I actually wanted is that I always get gotcha. how can I specialize a templated function to a particular template-parameter? or is that only possible for classes?

in the least my program is an example of how to confuse the reader. I mean, obviously the compiler could have also chosen to use function<M>(S) when I write function(S()) and produced an error because of the constructor or because of ambiguity! that's my question, how far can and do compilers deduce the right function to use? how does my program run on other compilers? the fixed sourcecode with header-inclusion:

#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;


template<typename T>
struct A
{
typedef typename T::C My;
string ToString() {return typeid(My).name();}
};

struct S
{
};

struct M
{
typedef S C;
};

struct D
{
typedef S C;
};

template<class T>
A<T> function(typename T::C)
{
cout<<typeid(T).name();
return A<T>();
}


A<D> function(D::C)
{
cout<<"gotcha!";
return A<D>();
}

int main(...)
{
A<D> out(function<D>(S()));
cout<<out.ToString();
A<D> out2(function(S()));
cout<<out2.ToString();
}
Last edited on
The compiler will not be able to call this function:

1
2
3
4
5
6
template<class T>
A<T> function(T::C)
{
cout<<typeid(T);
return A<T>();
}


because it will not be able to deduce T::C from the actual parameter. In other words, you can't
do that.

thanks for the reply. I guess it's a matter of style though, as it actually does compile and work. what I want is the other way around: from the template-parameter I give to function() the compiler should deduce which of the 2 functions of the same name it should use. that unfortunately doesn't work with vc10, and I would like to know if it works on other compilers. just try it and tell me what output you get! I get 2 typenames from out and 1 typename and a gotcha from out2.

also, what does the standard say on this situation? how should compilers behave in that situation? does the standard specify a possibility for specializing the template as opposed to specializing the parameters? if I would create a "class function" with an operator() or even with a static member-function (either being public), then I would get what I want (a template-function with specialization to a particular template-parameter), but not so with functions. is that inconsistency intentional? if yes, then I guess in future I will wrap up all my template-only functions into objects...
Your above example does compile and run, yes, though you have not specialized the function template
with your A<D> function( D::C ) function. If you attempted to specialize it:

1
2
template<>
A<D> function<D>( D::C ) {}


then it would not work.

Previously I wrote:
guestgulkan wrote:
By the way the two functions called function are not proper overloads - they are the same.


My error.
I had written down the second function as a template function as well - hence my remark.
Topic archived. No new replies allowed.