separating declaration from definition at templates

Hello, I want to clear whats happening with code where merely declaration is provided but definition resides in a separate compile unit.

function.hpp:
1
2
3
4
5
6
7
8
9
// function.hpp

#ifndef FUNCTION
  #define FUNCTION

  template <typename Container>
  void function( Container a_conatiner );

#endif 


function.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
// function.cpp

#include "function.hpp"
#include <iostream>

template <typename Container>
void function( Container a_container )
{
    for( auto item : a_container )
    {
        std::cout << item;
    }
}


main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// main.cpp

#include <string>
#include <vector>
#include <list>

#include "function.hpp"

int main()
{
    std::string my_word {"hello"};
    std::vector<int> my_vector { 1, 2, 3 };
    std::list<char> my_list { 'a', 'b', 'c' };

    function( my_word );
    function( my_vector );
    function( my_list );
}


I want to discuss what happens with such code and why it doesn't get linked.
Last edited on
The nature of templates require function declaration and definition reside together in a header file, you can not split it into a header and separate translation (.cpp) file.

A template is instantiated at compile time, not link time.
https://stackoverflow.com/questions/5612791/c-template-and-header-files
Last edited on
I want to discuss what happens with such code and why it doesn't get linked.

When you compile the function.cpp there is no objects, no functions, nothing to compile. Nothing requested, nothing made.

When you compile main.cpp, the main() calls:
1
2
3
void function<std::string>( std::string );
void function<std::vector<int>>( std::vector<int> );
void function<std::list<char>>( std::list<char> );

Where is their (object) code?
It can't be in main.o, because compiler sees only template <typename Container> void function( Container );
That makes sense.

I want to examine if the code would be linked if I would define explicitely @keskiverto's functions at a a compile unit.

But the compiler always says:

error: expected initializer before ‘<’ token
void function <std::list<char>> ( std::list<char> l )
              ^

at compiling this:
1
2
3
4
5
6
7
8
9
// fn_list.cpp

#include <iostream>
#include <list>

void function<std::list<char>> ( std::list<char> l )
{
    for( auto item : l ) std::cout << item;
}

Same error at the other function files.
I did not use the exact syntax for instantiation.
See https://en.cppreference.com/w/cpp/language/function_template
If you have a limited set of types for which your template may be instantiated, you may separate declaration/definition with explicit instantiation
http://www.cplusplus.com/forum/articles/14272/
Topic archived. No new replies allowed.