I am facing a few problems with “undefined reference to ” errors. I may not be able to post the code, but the declarations and the way I am calling the functions are as follows:
Declarations:
template <typename T>
int pitch_detect(deque<T>& x, int offset, int len);
template <typename T>
int is_voiced(
deque<T>& x, int offset, int len,
double avg_energy, int pre_voice,
short& s_flag,
long nsamples
);
I am calling the above functions as follows:
x = is_voiced(superFrame_, cur_offset_, f_len_,
avgEnergy_, frame_voicing_[1], silence_flag_, nsamples_);
y = pitch_detect(superFrame_, cur_offset_, f_len_);
The above statements (where I am calling the functions), get flagged as errors. These are the messages:
undefined reference to `int
is_voiced(std::deque >&, int, int,
double, int, short&, long)undefined reference to `int
pitch_detect(std::deque >&, int, int)’
Any help in decoding the above errors is most welcome.
Thanks,
Sriram
Edit:
The above functions are defined in a separate header and corresponding C++ file. I get no problems when I try to compile them and create an object file. These errors are seen in the linker stage.
Have you provided definitions for those templates? Are you explicitly instantiating the templates yourself or allowing the compiler to instantiate them?
If you provide a template declaration but the compiler does not see the definition in the same translation unit, it will assume that the template will be instantiated in another translation unit, and will just generate the call, but not compile (without seeing the definition it cannot possibly do it) the specific instantiation. Later at link time the linker will see the call, but will not see the instantiation and will fail with the undefined reference error.
The simplest solution is just having the template declaration and definition together:
Then when you use
is_voiced(...)the compiler will implicitly instantiate the template for you (it sees the code, and it will compile it).There are a few cases where you do not want the compiler to implicitly instantiate your templates (you know what types are going to be used, and you do not want the compiler to allow other uses –or it is expensive to compile and want to speed compilation up by only instantiating the templates in a single translation unit). For those cases you will need to provide your own explicit instantiation in a translation unit.
Then compile that implementation file and link it with the rest of the project.
Note: it is advisable to provide the full template definition in the header so that the compiler can implicitly instantiate it, unless you have a good reason not to do so.