Click here to Skip to main content
15,886,639 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
When I try to compile the following code I get an error about the specialization.

C++
#include <algorithm>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using namespace std;

class MyRandom {
public:
	MyRandom() {
		srand(time(0));
	}

	int operator() () const {
		return rand() % 10;
	}
};

template<typename T>
class MyPrint {
public:
	void operator() (T const& v) const {
		cout << v << endl;
	}

	template<>
	void operator() (int const& v) const {
		cout << "int:" << v << endl;
	}
};


int main() {
	int elements[10];

	generate(elements, elements + 10, MyRandom());

	for_each(elements, elements + 10, MyPrint<int>());

	return 0;
}


I don't get it, it seems ok to me :(
Posted

Try:
C++
#include <algorithm>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using namespace std;

class MyRandom {
public:
  MyRandom() {
    srand(time(0));
  }

  int operator() () const {
    return rand() % 10;
  }
};

template<typename T>
class MyPrint {
public:
  void operator() (T const& v) const {
    cout << v << endl;
  }
};

template <> void MyPrint<int>::operator()(int const &v) const { cout << "int: " << v << endl;}


int main() {
  int elements[10];

  generate(elements, elements + 10, MyRandom());

  for_each(elements, elements + 10, MyPrint<int>());

  return 0;
}


C++

 
Share this answer
 
v2
Comments
Sergejack 16-May-14 7:51am    
It works. So I can specialize a function template from inside the class declaration?
CPallini 16-May-14 7:59am    
I ma not an expert, but apparently you cannot (and it makes sense).
Sergejack 16-May-14 8:09am    
How does it make sense?
CPallini 16-May-14 8:13am    
It doesn't make sense (to me) to define the template specializations within the template class declaration itself.
Stefan_Lang 16-May-14 8:23am    
Asking why a form of template definition make sense is a bit like asking a fish why it doesn't swim backwards. ;-)

Seriously though: you've got to remember that the code inside your template class only gets analyzed by the compiler if it stumbles upon an instantiation of that class, and in that case it creates a class definition using the actual template arguments. I. e., at the time it looks at the member function, the class template arguments already are determined! Therefore, if you want a template class member function to behave differently for a specific instantiation, you need to define this outside the class definition.
The member function of a templated class cannot shed the class template parameter, which appears to be your intention. The compiler in fact treats the member function as a non-templated function within the specific instantiation of the templated class for a given class template argument. I. e., if you never instantiate the calss template, the compiler won't even notice, but if you do, the argument passed to the class template instantiation will be used and can't be a free template argument for member functions.

E. g. if you have the following code:
C++
template <class t>
class myT {
   T var;
public:
   void hello() const;
};
void foo {
   myT<int> x;
   x.hello();
}

Then the function hello will be instantated as myT<int>::hello().
 
Share this answer
 
v3
Comments
Sergejack 16-May-14 7:54am    
I don't really follow you. Could you explain it with other words?
Stefan_Lang 16-May-14 8:15am    
You can declare template classes and template functions. Your class MyPrint is declared as a template class. When you used a template syntax for your member function operator() however, that was template function syntax, and the argument list defined therein only applies to the function.

If you define anything within the template class definition, you always refer to the (unspecified) template arguments. If you want to refer to specific values of a template argument, you need to make a separate definition, like CPallini did in his solution.

I wasn't even aware that was possible, but CPallini did the right thing: instantiate the member function for the specialized class.
CPallini 16-May-14 8:02am    
My 5. By the way, many thanks for having made the damned CodeProject 'styler' work on my answer.
Stefan_Lang 16-May-14 8:24am    
Thanks, and yw!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900