unqualified-id error before ')' token [duplicate] - c++

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 6 years ago.
I am new to stack overflow and I would appreciate feedback. I am creating a template graph class and have split it into two files graph.h and graph.hpp, but everytime I compile I get this error:
In file included from graph.h:97:0,
from main.cpp:2:
graph.hpp:4:26: error: expected unqualified-id before ‘)’ token
typename graph<T>::graph(){
^
makefile:2: recipe for target 'executable.x' failed
Here is my graph.hpp file so far:
#include "graph.h"
//template <typename T>
typename graph<T>::graph(){
numVertices = 0;
graphWeight = 0;
}
And my graph.h file looks something like:
template <typename T>
class graph{
public:
graph();
.
.
.
private:
};
Also, my main.cpp is just simply:
#include "graph.h"
int main(){
graph<int> g;
}
What could possibly be wrong? I know it's probably something simple that has to do with the template.
Thanks

In your graph.hpp snippet, change your code to this
#include "graph.h"
template <typename T>
graph<T>::graph(){ //Constructor has no return type.
numVertices = 0;
graphWeight = 0;
}
Unfortunately, you have cannot really have separate header and implementation file for templates, so put the implementation in your header file. For more info and workarounds, see Why can templates only be implemented in the header file?

Related

Understanding how imports are working in C++

I'm trying to understand how including works in C++. I have two questions about it. The first one is on how properly import the .h file. For example I created the following HashNode.h file:
namespace HashNode{
template<class Data>
class HashNode{
private:
Data data;
HashNode *next;
public:
explicit HashNode(const Data &data);
Data getKey();
~Node();
};
}
So in the HashNode.cpp file, it should like:
#include "HashNode.h"
using namespace HashNode;
template <class Data> // ~~~ HERE 1 ~~~
HashNode::HashNode(const Data &data) {//todo};
template <class Data> // ~~~ HERE 2 ~~~
Data* HashNode::getKey() {
//todo
}
HashNode::~Node() {
//todo
}
This way it works but do I have to include template <class Data> beside each function which uses Data? Why it does not recognize Data without including template <class Data>?
Also I have created the Hash.h file which should use the HashNode.h file:
#include "HashNode.h"
using namespace HashNode;
namespace Hash {
template <class Data>
class Hash {
typedef enum {
GOOD = 0,
BAD = -1,
BAD_ALLOC = -2
} Status;
private:
HashNode **hash;
int capacity;
int size;
public:
explicit Hash(int size);
Status insertData(const Data &data);
~Hash();
};
}
But I get the the following error: Can't resolve type 'HashNode'. Why it can't see the import?
In the Hash.cpp file I get Unused import statement for #include "HashNode.h". Why is that?
Also, what if I want to include private functions - should them be in the .h file or in the .cpp file?
The member functions of a template class are themselves also templates. Because of this, they need to be defined with any required template parameters and template type definitions.
About your second question, it has to do with namespaces. As I see it, having namespace and class under the same naming might cause you ambiguity. Although, everything seems to be fine on the structural side of the code. Try using #pragma once or some kind of guards to prevent this kind of issues.

Linking multiple files with template class in another .cpp file

I am learning template programming and have come across an error i cannot understand. My task involves 3 files
1) A main File (with main function)
#include<iostream>
#include "templates.h"
int main(){
trial <int>x;
x.input(3);
std::cout<<x.ret();
return 0;
}
2) A header File
#ifndef templ
#define templ
template<typename T>
class trial{
T val;
public:
void input(T x);
T ret();
};
#include "templateref.cpp"
#endif
3) A .cpp file used define the functions of class trial
#ifndef templ
#define templ
#include"templates.h"
#endif
template<class T>
void trial<T>::input(T x){
val = x;
return ;
}
template<class T>
T trial<T>::ret(){
return val;
}
As i undestand from here "Undefined reference to" template class constructor and https://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp i had to instantiate the template class for it to work.
My problem occurs when I try to compile it.
when I do
clang++ templates.cpp templateref.cpp -Wall -o template
I get the error
templateref.cpp:14:6: error: variable has incomplete type 'void'
void trial<T>::input(T x){
^
templateref.cpp:14:11: error: expected ';' at end of declaration
void trial<T>::input(T x){
^
;
templateref.cpp:14:11: error: expected unqualified-id
templateref.cpp:20:11: error: qualified name refers into a specialization of variable template 'trial'
T trial<T>::ret(){
~~~~~~~~^
templateref.cpp:14:6: note: variable template 'trial' declared here
void trial<T>::input(T x){
^
4 errors generated.
This is fixed by
clang++ templates.cpp -Wall -o template
the compilation runs without errors and gives results as expected .
So my question is (sorry for the long explanation , as i couldnt explain my question in shorter words) why cant I link these files together and what am i missing?
You shouldn't compile the member definition file – it's already included in the header.
Due to the include guard in that file, the entire header is excluded when the compiler processes it, and the class template definition doesn't exist.
Just compile the main file.

compile header files defines a template class which also includes other header files [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
JUST to make it clear : it is different from the problem that we must define functions of template class in the header file.
UPDATE : if you need the real source code, you can download it here : https://Near#bitbucket.org/Near/compile_error.git
I implement a double list class.
// list.h //
class list {
//...
void insert(...);
};
// list.cpp //
#include "list.h"
void list::insert(...) {
...
}
I also implement a template class which include the list.h
// template_class.h //
#include "list.h"
template<class T>
class temp_class {
list l;
void func();
}
void temp_class::func() {
//...
l.insert(...);
}
Now I write a test.cpp file which include the template_class.h and call the func function
// test.cpp //
#include "template_class.h"
int main() {
temp_class<int> t;
t.func();
return 0;
}
I compile like this
g++ test.cpp list.cpp -o test
The compiler complains that test.cpp : "undefined reference to insert".
Why can't it work? How to solve this error?
FYI : If I include the content in list.cpp in list.h and just compile test.cpp, it works. But I don't think it is a good idea.
When compiling your code I immediately get the warning:
list_double.h:14:15: warning: inline function ‘void list_double_node::list_double_insert_first(list_double_node*)’ used but never defined [enabled by default]
void inline list_double_insert_first(list_double_node* entry);
That is, your code is actually akin to this SSCCE:
// list.h
class list {
public:
inline void insert(int);
};
.
// list.cpp
#include "list.h"
void list::insert(int) {
}
.
// template_class.h
#include "list.h"
template<class T>
class temp_class {
list l;
public:
void func();
};
template <class T>
void temp_class<T>::func() {
l.insert(17);
}
.
// test.cpp
#include "template_class.h"
int main() {
temp_class<int> t;
t.func();
return 0;
}
The fix is: either remove the inline or define the function in the header. The rules for inline are actually pretty much the same as those for template: whenever an inline function is used, its implementation has to be provided.

C++ undefined reference to class that uses template [duplicate]

This question already has answers here:
Why do I get "unresolved external symbol" errors when using templates? [duplicate]
(3 answers)
Closed 9 years ago.
I'm pretty new with templates, so please don't be harsh on me if my code is very wrong :)
This is the header file for a class Key that uses a template:
//Key.h
#ifndef KEY_H
#define KEY_H
#include "../Constants.h"
template<class KeyType>
class Key
{
public:
Key<KeyType>(KeyType initial);
KeyType increment();
private:
KeyType current;
};
#endif /* KEY_H */
This is the .cpp file of Key class:
//Key.cpp
#include "Key.h"
template<class KeyType> Key<KeyType>::Key(KeyType p_initial)
{
this->current = p_initial;
}
template<class KeyType> KeyType Key<KeyType>::increment()
{
this->current ++; //KeyType should implement this operator
}
So what's the problem? I try to create an instance of Key somewhere else in my code, like this:
Key songID (0); // ERROR: undefined reference to Key<int>::Key(int)
and then use
songID.increment(); // ERROR: undefined reference to Key<int>::increment()
Two points:
Remove <KeyType> from Key<KeyType>(KeyType initial); you don't need it.
And, move class implementation from .cpp file to .h file. Thie article is useful: Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?

using template declared in other file in c++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can templates only be implemented in the header file?
What is an undefined reference/unresolved external symbol error and how do I fix it?
I have defined a template class in a file.
point.h is
#ifndef POINT_H
#define POINT_H
using namespace std;
template <typename T, int size>
class point {
private:
T coordinates[size];
public:
point();
void set_coordinates(const T *);
void get_coordinates(T *);
};
#endif /* POINT_H */
point.c is
#include "point.h"
template <typename T, int size>
point::point() {
for (int i = 0; i < size; i++)
coordinates[i] = 0;
}
template <typename T, int size>
void point<T, size>::set_coordinates(const T *coordinates) {
for (int i = 0; i < size; i++)
this->coordinates[i] = coordinates[i];
}
template <typename T, int size>
void point<T, size>::get_coordinates(T *coordinates) {
for (int i = 0; i < size; i++)
coordinates[i] = this->coordinates[i];
}
I am using this template as point<int, 2> p0;. But compiler gives error that point<int, 2> is not defined.
I searched on this and found two solutions -
1. to use export variable. But I read that it is not supported by all compilers. So, I don't want to use that.
2. to create explicit class specializations like
template <> class point<int> {
...
}
But isn't there any other way to do this? (I mean in C++ standard containers, they might have used some technique to do this.)
Read this and the next two FAQ questions - C++ FAQ
The solution of the c++ standard containers is keep everything in the header file.
You should put all the definitions belonging to the template point (that is, including the member functions) to the point.h file and include it in any file that uses the point class, so that the compiler can instantiate it as needed. See this question for details.
The C++ compilers and linkers have means to avoid "multiple definitions" error on link (the ODR rule in the standard states this must be the case).