C++ templates

Feb 18, 2019 at 10:27pm
I'm trying C++ templates for the first time and I'm struggling to understand why I get this compilation error:

error LNK2019: unresolved external symbol "public: void __thiscall puzzle::create<char const *>(char const *)" (??$create@PBD@puzzle@@QAEXPBD@Z) referenced in function _main

the full code is:

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
class puzzle {
private:
	std::unique_ptr<std::vector<std::string>> correct_order{};
	std::unique_ptr<std::vector<std::string>> current_order{};

public:
	puzzle();
	~puzzle();

	template <typename... Args>
	void create(Args... args);

	void menu();
	void print();
};


puzzle::puzzle()
{
	correct_order = std::make_unique<std::vector<std::string>>();
}

puzzle::~puzzle()
{
	correct_order.reset();
}

template<typename... Args>
inline void puzzle::create(Args... args)
{
	for (auto& i : args)
	{
		correct_order->push_back(i);
	}
}

void puzzle::menu()
{

}

void puzzle::print()
{
	for (auto& i : *correct_order)
	{
		std::cout << &i;
	}
	std::cout << std::endl;
}

int main(void)
{
	puzzle p;
	p.create("test1", "test2", "test3", "test4");
	p.print();
}




Any help/advice appreciated
Feb 18, 2019 at 11:07pm
The definition of function templates need to be available everywhere where it's used so normally all template code is put into the header file. Don't worry about the one-definition rule. There is an exception in the rules for templates so it will work fine as long as the definition is the same everywhere.
Feb 19, 2019 at 8:30pm
thanks Peter, I removed the function from the .cpp file and put the definition in the header, I now have another problem though:

puzzle.h(19): error C3520: 'args': parameter pack must be expanded in this context
main.cpp(30): note: see reference to function template instantiation 'void puzzle::create<const char*,const char*,const char*,const char*>(const char *,const char *,const char *,const char *)' being compiled
puzzle.h(18): error C3312: no callable 'begin' function found for type 'unknown-type'
puzzle.h(18): error C3312: no callable 'end' function found for type 'unknown-type'
puzzle.h(21): error C2065: 'i': undeclared identifier

on code of

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename... Args>
	inline void create(Args... args)
	{
		for (auto &i : args)
		{
			correct_order->push_back(i);
		}
	}

nt main(void)
{
	puzzle p;
	p.create("test1", "test2", "test3", "test4");
	p.print();
}


Can you advise the correct way to do template like this? Basically everytime I construct a puzzle I'll always pass in X number of strings only, using this create function
Last edited on Feb 19, 2019 at 8:32pm
Feb 19, 2019 at 8:45pm
You cannot iterate through a parameter pack using a range-based for loop.

Easiest way to do what you are trying to do is to use a fold expression.

1
2
3
4
5
template<typename... Args>
inline void puzzle::create(Args... args)
{
	(correct_order->push_back(args), ...);
}
Topic archived. No new replies allowed.