Missing type specifier- int assumed

I am trying to build a solution in Visual Studio and the compiler keeps throwing the error: "missing type specifier- int assumed. Note: C++ does not support default-int" in my "exercise13class.h" file on the line where the constructor is initialized. I have looked up the error and it sounds like it may have something to do with circular dependency. I have looked over my code and read about circular dependency but I still feel confused as to what I am doing incorrectly. Is it that my header file declares a template that my main cpp file has to define? Does anyone know what is going on here?

Here are the relevant files:

"exercise13.cpp"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <string>
#include <iostream>
#include <vector>
#include "exercise13class.h"

using namespace std; 

int main()
{
	Collection<int> arrayOfInts;
	Collection<string> arrayOfStrings;

	arrayOfInts.insert(55);
	arrayOfInts.insert(30);
	arrayOfInts.insert(100);
	arrayOfInts.insert(8000);

	cout << "Is array empty?: " << arrayOfInts.isEmpty() << endl;
	cout << endl;

	cout << "Does array contain?: " << 55 << ": " << arrayOfInts.contains(55) << endl;
	cout << "Does array contain?: " << 100 << ": " << arrayOfInts.contains(100) << endl;
	cout << "Does array contain?: " << 9999 << ": " << arrayOfInts.contains(9999) << endl;
	cout << endl;

	arrayOfInts.makeEmpty();

	arrayOfInts.insert(88);
	arrayOfInts.insert(2000);
	arrayOfInts.insert(99);

	cout << "Is array empty?: " << arrayOfInts.isEmpty() << endl;
	cout << endl;

	cout << "Does array contain?: " << 88 << ": " << arrayOfInts.contains(55) << endl;
	cout << "Does array contain?: " << 2000 << ": " << arrayOfInts.contains(100) << endl;
	cout << "Does array contain?: " << 9999 << ": " << arrayOfInts.contains(9999) << endl;
	cout << endl;

	arrayOfInts.makeEmpty();

	arrayOfStrings.insert("duck");
	arrayOfStrings.insert("goose");
	arrayOfStrings.insert("water fowl");
	arrayOfStrings.insert("pigeon");

	cout << "Is array empty?: " << arrayOfStrings.isEmpty() << endl;
	cout << endl;

	cout << "Does array contain?: " << "duck" << ": "
 << arrayOfStrings.contains("duck") << endl;
	cout << "Does array contain?: " << "goose" 
<< ": " << arrayOfStrings.contains("goose") << endl;
	cout << "Does array contain?: " << "Not a bird" << ": " 
<< arrayOfStrings.contains("Not a bird") << endl;
	cout << endl;

	arrayOfStrings.makeEmpty();

	return 0; 
}


"exercise13class.h"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef EXERCISE13_H
#define EXERCISE13_H

using namespace std;

template <typename Object>
class Collection
{
public:
	explicit Collection(const vector<Object> & initialArray = vector<Object>{})
		: storedArray{ initialArray } { }

	bool isEmpty();

	void makeEmpty();

	void insert(const Object & arrayValue);

	void remove(const Object & arrayValue);

	bool contains(const Object & arrayValue);


private:
	vector<Object> storedArray;
};

#endif


"exercise13class.cpp"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "exercise13class.h"

template<typename Object>
bool Collection<Object>::isEmpty()
{
	if( storedArray.empty() )
	{
		return true;
	}
	else
	{
		return false; 
	}
}

template<typename Object>
void Collection<Object>::makeEmpty()
{
	storedArray.clear(); 
}

template<typename Object>
void Collection<Object>::insert( const Object & arrayValue )
{
	storedArray.push_back( arrayValue ); 
	
}

template<typename Object>
void Collection<Object>::remove( const Object & arrayValue )
{
	for( unsigned int i = 0; i < storedArray.size(); i++ )
	{
		if( storedArray[i] == arrayValue )
		{
			storedArray.erase(storedArray[i]);
		}
	}
}

template<typename Object>
bool Collection<Object>::contains( const Object & arrayValue )
{
	for( unsigned int i = 0; i < storedArray.size(); i++ )
	{
		if( storedArray[i] == arrayValue )
		{
			return true;
		}
	}
	
	return false; 
}
Last edited on
Why do you appear to have two files named exercise13class.h?

By the way when dealing with templates you need to make sure both the definition and the declaration are in the same compilation unit. This usually means that the whole class is in a single header file.

You've forgot to include <vector> in exercise13class.h.
@jib- I don't. Haha. That was a mistake. I corrected the names of the files above.
@jib- I thought having the declarations and definitions for a class in separate files was beneficial so that if multiple files are instantiating objects based off of the same class file the linker won't throw any errors because of multiple definitions. I might be wrong and I might be misunderstanding how that works. I was under that impression because of a recent post I made:http://www.cplusplus.com/forum/general/248394/. See specifically the discussion between @TheIdeasMan and me.

@Peter87- wouldn't putting <vector> in exercise13class.h mean that when exercise13.cpp imports the exercise13class.h header file that <vector> will be imported twice and the complier or linker will throw an error? I might be misunderstanding how importing those standard library classes works.
The header <vector> may be included any number of times; the effect is as if it was included just once.

A translation unit may include library headers in any order. Each may be included more than once, with no effect different from being included exactly once... http://eel.is/c++draft/using.headers#2


This is in general true for all well written headers; see: https://en.wikipedia.org/wiki/Include_guard
I thought having the declarations and definitions for a class in separate files was beneficial

When you're dealing with non-template classes this is true. However when working with template classes both the class definition and the class implementation must be in the same compilation unit. This usually leads to template classes being defined and implemented in a single header file.

so that if multiple files are instantiating objects based off of the same class file the linker won't throw any errors because of multiple definitions.

Template classes are different, basically they are created inline for every instance of the template class.

@JLBorges- so for library headers you SHOULD include it in every relevant file, but for user created header files you SHOULDN'T? Is that correct?
Every required header should be included in every file (translation unit).

User created headers should have #include guards to eliminate problems with multiple inclusion.
See: https://stackoverflow.com/questions/8020113/c-include-guards#8020211
@JLBorges- so with header guards you don't have to worry about multiple inclusion at all? So in fact, it's only a problem if you don't have them?
We shouldn't be defining objects or non-inline functions with external linkage in a header file.
Then, with header guards, multiple inclusion would not cause a problem.

Some guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#S-source
Thank you for that thorough link, @JLBorgees.

Thanks everyone else for helping me understand all of this stuff. My program runs as expected both in Visual Studio and when I compile it in my Unix terminal.
Topic archived. No new replies allowed.