Jump to content
  • Advertisement
Sign in to follow this  
incin

c++ call overloaded func from template?

This topic is 3262 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This code works as expected in visual studio and older versions of g++ (prior to 4.x). But in g++, my 'run_test' function doesn't see overloads of test() which appear later. The only workaround I have is to ensure by ordering my include files that run_test() appears last so it picks up all the overloads. If anyone has a work around for this, that would be awesome. Also, how does this relate to the c++ standard, anyone? Any answers would help right now, I've spent a long time trying to figure this out -- ordering becomes even more complicated to resolve when you have inter-dependencies. You can run g++ 4 with this code here: http://codepad.org/v3NW1Om6
#include <iostream>

template <typename T>
void test(T&);

void test(int&)
{ std::cout << "Int\n"; }

template <typename T>
void run_test(T& v)
{  
  test(v);
}

void test(float &)
{ std::cout << "float\n"; }


int main()
{  
   float f;
   int i;
   run_test(f);
   run_test(i);
   return 0;
}
template <typename T>
void test(T&)
{ std::cout << "Unspecialized\n"; }

//Outputs:
//Unspecialized
//Int

Share this post


Link to post
Share on other sites
Advertisement
Im not sure if this is the problem you're having, but your syntax is incorrect for the template specialization:
void test(float& f)
should be:
template< > void test<float>(float& t)

try this code:


#include <iostream>

template <typename T>
void test(T&);

template <>
void test<int>(int&)
{ std::cout << "Int\n"; }

template <typename T>
void run_test(T& v)
{
test(v);
}

template< >
void test<float>(float &)
{ std::cout << "float\n"; }


int main()
{
float f;
int i;
run_test(f);
run_test(i);
return 0;
}
template <typename T>
void test(T&)
{ std::cout << "Unspecialized\n"; }

Share this post


Link to post
Share on other sites
Quote:
Original post by incin

Also, how does this relate to the c++ standard, anyone?


Templates are instantiated when they are used. When run_test is instantiated, float specialization doesn't exist yet.

For example (MVC):
#include <iostream>

template <typename T>
void test(T);

void test(int&)
{ std::cout << "Int\n"; }

template <typename T>
void run_test(T v)
{
test(v);
}

template <>
void run_test<float>(float f) {
test(f);
}

void test(float f)
{ std::cout << f << " float \n"; }

int main()
{
float f;
int i;
run_test(f);
run_test(i);
return 0;
}
template <typename T>
void test(T)
{ std::cout << "Unspecialized\n"; }


Prints
Quote:
Unspecialized
Int


But moving test(float) higher up resolves it.

GCC is basically correct about this, but MVC seems to have some usual conveniences built in, and only succeeds in some cases.

Short version - all specializations must be included before template is instantiated.

Personally, I can't recall encountering this type of problem. Maybe it has something to do with code structure.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
...
Templates are instantiated when they are used. When run_test is instantiated, float specialization doesn't exist yet. ...


But the float specialization does exist when the template is instantiated, both run_test<float>() and test<float>() are instantiated from main(), right?

Share this post


Link to post
Share on other sites
Quote:
Original post by silvermace
Im not sure if this is the problem you're having, but your syntax is incorrect for the template specialization:
void test(float& f)
should be:
template< > void test<float>(float& t)

try this code:

*** Source Snippet Removed ***


Strangely enough, changing to use template specialization syntax allows me to call the float function. However, this doesn't fix my problem since partial template function specialization is illegal, ie this won't compile:

template <typename T>
void test<std::vector<T> >(std::vector<T>&)
{
std::cout<<"vector";
}

This will compile, but leaves me with an ordering problem again:
template <typename T>
void test(std::vector<T>&)
{
std::cout<<"vector";
}

Share this post


Link to post
Share on other sites
Or you could simply move the float version up to before run_test.

Also, I feel like pointing out there is no specialization at all in this code. There are overloads, which usually ARE prefered to templates, but not if the overload hasn't even been declared yet.

Try this:

void run_test(int x) { test(x); }
void test(int x) {}




It won't compile, because test must be declared before run_test. In exactly the same way your float overload isn't known to run_test and so it has to fall back to the template version.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!