0

I am currently working in Ubuntu9.10 - c++. I need to define an generic object in a method. I have to define the method in .h file. How can I do it? I did the following:

file.h

class ana

{
//code
public:
template <class T>  bool method (T &Data);
};

file.cpp

//code

template <class T>
bool ana::method(T &Data)
{
//code
}

I've created the .a file.

In test.cpp:

//code
main()
{
    //code
    Ana* ann = new Ana();

    if (ann->method(*ann)){//code}
}

After compiling with g++ test.cpp -o test libfile.a I have the error: undefined reference to bool.... Why? Is there another way to create a generic object?

Sriram
  • 10,298
  • 21
  • 83
  • 136
linuxx
  • 1,487
  • 4
  • 16
  • 17
  • 3
    All the template code must go in the header. –  May 09 '11 at 13:40
  • @unapersson, you should submit this as an answer, not a comment. – Trent May 09 '11 at 13:42
  • 2
    @Trent Actually, I should vote to close it as a dupe, but I can't be arsed finding one of the zillions of questions its a dupe of. –  May 09 '11 at 13:45
  • 1
    possible duplicate of [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Robᵩ May 09 '11 at 14:38

5 Answers5

2

The usual problem. Have a look: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13.

Just put everything into a header file.

file.hpp

class ana
{
    //code
public:
    template <class T>  bool method (T &Data)
    {
        //code
    }
};

Include this in your main.cpp and it should work fine.

#include "file.hpp"
main()
{
    //code
    Ana* ann = new Ana();

    if (ann->method(*ann)){//code}
}
mkaes
  • 13,781
  • 10
  • 52
  • 72
  • 1
    It is poor practice to answer with just a link. http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers – Jordan May 09 '11 at 13:45
  • can you please tell me how to change the code i have? please?:) I am stack – linuxx May 09 '11 at 13:47
  • I agree that it is poor practice. But I guess if I would use the search I would find this is a duplicate. Nevertheless thanks for the meta link. That was new to me. – mkaes May 09 '11 at 13:56
  • Works fine on my machine. Beside of the typo I copied from you that it must be lower cap `ana* ann = new ana();` – mkaes May 09 '11 at 14:35
1

Putting function definitions together with declarations (in the header files itself) definitely helps and is the way of choice. But, in case you want to separate the function definitions, have the following lines at the end of the .cpp file. Its called explicit instantiation.This will take care of linker errors. I tried some code, and this seems to work, based on what you have given:

file.h:

#ifndef __ANA_H__
#define __ANA_H__

template <class T>
class ana {

  public: 
    bool method(T& data);
};

#endif

file.cpp:

#include <ana.h>
#include <iostream>
using namespace std;

template <typename T>
bool ana<T>::method(T& data) {
  cout << "Data = " << data << endl;
  if(data > 0) {
    return true;
  }
  return false;
}

//explicit instantiation for avoidance of g++ linker errors.
template
bool ana<int>::method(int& data);

template
bool ana<double>::method(double& data)

One of the downsides of using this method is that these lines will have to be included for every data type that you want this function to support. So, now the method function will run ONLY for int and double. The specs for your code should be such that method is never called for data types other than the above. HTH,
Sriram

Sriram
  • 10,298
  • 21
  • 83
  • 136
  • @linuxx: I have edited my post and posted some code that works for me. – Sriram May 09 '11 at 18:58
  • @Sriram I have another question: if in: method i have (T &data, Ana::Subclass &z) and Subclass is a subclass of Ana class// class Ana{ .. class Subclass{}*subcls}; I receive that Ana::Subclass &z is not a type. How to resolve it? Please tell me.THX – linuxx May 10 '11 at 09:26
  • @linuxx: Subclass is not really a subclass. it is a nested class. – Sriram May 10 '11 at 10:02
  • @linuxx: You can upvote by clicking on the up-vote symbol on the top-left corner of THIS answer, right below where it says "4 answers" – Sriram May 10 '11 at 10:04
  • Can you tell me how to update the code if i have in the method a pointer to a nested class? please! //method(T &data, class::nestedclass &x); – linuxx May 10 '11 at 10:10
  • @linuxx: I suppose method(T& data, nestedclass& x) should do the needful. – Sriram May 10 '11 at 10:12
  • @linuxx: It seems to me that your basics in C++ are not that clear. Is this the language you usually code in or are you just starting out? – Sriram May 10 '11 at 10:13
  • Sriram I did that method(T &data, nestedclass &x) but i still have the error:(. The thing is that i have more than one nested classes and i also use this ana::subclass nested class in other methods:(. I don't know how to resolve this problem. PLEASE HELP! – linuxx May 10 '11 at 10:15
  • @linuxx: I notice you have already put this question up elsewhere. Why dont you take that answer and work with that? – Sriram May 10 '11 at 10:25
0

Just include cpp file in main.cpp like this: #include "ana.cpp" and you will not have errors.

0
  1. You forgot to build file.cpp into the binary.
  2. You should put the function template definition in the header, anyway.
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • what do you mean? where am i wrong? can you please rewrite my code? – linuxx May 09 '11 at 13:46
  • i don't need to build the file.cpp because i build the .a file – linuxx May 09 '11 at 13:48
  • @linuxx You can start by inlining the implementation of `template bool method (T &Data)`, in the __header__. Also, it should be `class Ana`, not `class ana`. The main point is that the template method must be implemented in the header. – juanchopanza May 09 '11 at 13:54
  • No for #1. For non-template functions, you provide the header and the compiled library, and you're fine. For template functions, the compiler has to be able to see the implementation at the point of use, and so it needs to be in the header, so whether file.cpp is in the binary or not is irrelevant. – David Thornley May 09 '11 at 13:56
  • @David: I know. #2 subsumes #1. But #1 is a _general_ error that he has made whilst under the assumption that the function definition goes in `file.cpp`: it was left out of the build altogether. – Lightness Races in Orbit May 09 '11 at 14:01
  • I don't understand:). could you please give me an correct example? PLEASE:) – linuxx May 09 '11 at 14:04
  • Actually I missed `libfile.a`; there was no compilation line posted for it. Indeed _only_ #2 applies to this question. – Lightness Races in Orbit May 09 '11 at 14:07
0

You need to change the definition of your method() method to be in the header file:

class ana
{
public:
    template <class T>
    bool method (T &Data)
    {
        // Do whatever you want in here
    }
};

Check the following link out for a detailed explanation - http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

Mark Ingram
  • 71,849
  • 51
  • 176
  • 230
  • Mark I am using the .h file just for declaring the method. I don't want to also define the method in the .h file . I am using file.cpp for this. – linuxx May 09 '11 at 13:55
  • You *have* to define the method in the header file, you don't have a choice :) – Mark Ingram May 09 '11 at 14:05
  • how do i have to define it in the method file? please give me the full code. – linuxx May 09 '11 at 14:19