Weird Linker Error

I was going back through Principles and Programming by Stroustrup and after completing the chapter 6 exercise I was left with these weird linker errors with very unhelpful messages (to me). Does anyone know what's wrong here?

/* error LNK2019: unresolved external symbol "public: __thiscall Token_stream::Token_stream(void)" (??0Token_stream@@QAE@XZ) referenced in function "void __cdecl `dynamic initializer for 'ts''(void)" (??__Ets@@YAXXZ) */

/* error LNK1120: 1 unresolved externals */

Source code:

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "std_lib_facilities.h";

class Token
{
public:
	char kind;
	double value;
};
class Token_stream
{
public:
	Token_stream();
	void putback(Token t);
	Token get();
private:
	bool full{ false };
	Token buffer;
};

void Token_stream::putback(Token t)
{
	if (full) error("putback() into full buffer.");
	buffer = t;
	full = true;
}
Token Token_stream::get()
{
	if (full)
	{
		full = false;
		return buffer;
	}
	char ch;
	cin >> ch;

	switch (ch)
	{
	case ';':
	case 'q':
	case '(': case ')': case '+': case '-': case '*': case '/':
		return Token{ ch };
	case '.':
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	{
		cin.putback(ch);
		double val;
		cin >> val;
		return Token{ '8', val };
	}
	default: error("Bad token");
	}
}

Token_stream ts;
double expression();

double primary()
{
	Token t = ts.get();
	switch(t.kind)
	{
	case '(':
	{
		double d = expression();
		t = ts.get();
		if (t.kind != ')')error("')' expected");
		return d;
	}
	default: error("primary expected");
	}
}
double term()
{
	double left = primary();
	Token t = ts.get();

	while (true)
	{
		switch (t.kind)
		{
		case '*': left *= primary();
			t = ts.get();
			break;
		case '/':
		{
			double d = primary();
			if (d == 0) error("divide by zero");
			left /= d;
			t = ts.get();
			break;
		}
		default:
			ts.putback(t);
			return left;
		}
	}
}
double expression()
{
	double left = term();
	Token t = ts.get();

	while (true)
	{
		switch (t.kind)
		{
		case '+': left += term();
			t = ts.get();
			break;
		case '-': left -= term();
			t = ts.get();
			break;
		default:
			ts.putback(t);
			return left;

		}
	}
}

int main()
{
	try
	{
		double val{ 0 };
		while (cin)
		{
			Token t = ts.get();

			if (t.kind == 'q') break;
			if (t.kind == ';') cout << "=" << val << endl;
			else ts.putback(t);
			val = expression();
		}
	}
	catch (exception& e)
	{
		cerr << e.what() << endl;
		keep_window_open();
		return 1;
	}
	catch (...)
	{
		cerr << "exception" << endl;
		keep_window_open();
		return 2;
	}
}
Last edited on
The error message is saying that you never defined the body for the Token_stream class' constructor. It looks like you don't really need a constructor for the class any way so you could just use a default constructor.

1
2
3
4
5
6
class Token_stream
{
public:
	Token_stream(); // try removing or commenting out this line and see if that fixes things
	void putback(Token t);
	Token get();
You're awesome it worked perfectly! Thank you so much. I can't believe I didnt consider that before.
Topic archived. No new replies allowed.