views:

130

answers:

5

I wonder if it is a good practice to have a member template function inside a non-template class in c++? Why?

I'm trying to do something like this

in classA.h:
classA
{
   public:
      member_func1();
      member_func2();
};

in classA.cpp:
template <class T> share_func();

classA::member_func1()
{
   call share_func();
}
classA::member_func2()
{
   call share_func();
}

I wonder if it is appropriate?

+3  A: 

If the member function logically belongs in your class, and the template type is specific to only that function (and has nothing to do with the rest of your class), I don't see any reason not to do this.

Brian R. Bondy
+3  A: 

That's a perfectly legitimate use of template functions. Additionally, there's no problem with using templated member functions of a non-template class. For example:

class A {
   public:
     void say_hello() { cout << "Hello World" << endl; }
     template<T> print_it( T arg ) { cout << "Argument: " << arg << endl; }
};
...
A a;
a.say_hello();
a.print_it( 3.14159 );
a.print_it( "A string" );
Rakis
A: 

Templating a function is a simple way of overloading it with different argument types, which is perfectly acceptable. In that sense, it's even acceptable to template a single member function in a non-template class, or call a template function from a non-template class. There's nothing ambiguous about it

Andrew Noyes
A: 

If you have many methods that have similar signatures, only varying by type, a template method is the way to go:

struct Example
{
   void load_from(std::istream&);
   void load_from(Database_Table&);
   void load_from(Some_Device&);
};

A template method would allow some expansion:

struct Example_Template_Method
{
    template <class Input_Source>
    void load_from(Input_Source&);
};

The key point here is that a template allows for a method, function or algorithm to operate on different types of objects without changing the algorithm. This can also apply to interfaces as well.

Thomas Matthews
A: 

Yes it's good, of course as usual you'd better factorize as much out of the template as possible.

For example:

class Tokens
{
public:

  void add(const char* c);
  void add(const std::string& s);

  template <class T>
  void add(T const& t)
  {
    this->add(boost::lexical_cast<std::string>(t));
  }

private:
  std::vector<std::string> mTokens;
};

This relieves the tedium of the conversion from the user's lap.

Matthieu M.