Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Template Library files and Header linking troubles

19 views
Skip to first unread message

Popping mad

unread,
Nov 5, 2016, 11:41:33 AM11/5/16
to

I've been trying to create some custom system libraries with templating
and it surprised me when I starting to get linking problems. Generally I
create a .h file and a .cpp file and develop objects which can later be
developed into shared libraries. Years ago I did quite a bit of work
with C++ and libraries and I don't recall having this problem, but looking
back at the code, I see I was cramming a lot of class definitions directly
into the .h file. So I must have hit this snag before but I don't
remember it.

You'll have to excuse me if I sound a little vague on this problem I am
having, but it is very complicated and I'm slow at getting my head around
this issue. And it seems to affected somehow by name space.

I'm looking over the text by Vandevoorde and Josuttis, "C++ Templates The
complete guild, 12th printing in June of 2010 and copyrighted in 2003.
They seem to sum up the problem fairly well, although there explanation
is a bit cryptic to me. Section 6.1.1 and 6.1.2 on pages 63 after show
some sample code of a 3 file break out of C++ code they write:

A C++ compiler will most likely accept this program
without any problems, but the linker will probably
report an error, implying that there is no definition
for the function print_typeof()...

(adlib) for a common solution...
We include the defintions of a template in the header
file that declares that template.. For our example,
we can do this by adding

#include "myfirst.cpp"

at the end of myfirst.cpp in every do-C file that uses
the template. A third way, or course, is to do away
with myfirst.cpp and rewrite myfirst.hpp so that it
contains all template declarations and template
definitions.


Ugg. So I'm looking over old code that I wrote and it seems that
namespace influences the result of this, at least with gcc on GNU.

In this file here, I seem to be having no problem creating templated
objects in a .cpp file, but everything is being dumped the std namespace

http://www.nylxs.com/docs/workshops/linklist_templates/linklist.cpp.html

1 #include "linklist.h"
2 #include <iostream>
3
4 using namespace std;
5
6 template<class unk>
7 NODE<unk>::~NODE<unk>(){
8 //cout << "List Item Destroyed" << endl;
9
10 }
11
12
13
14
15 template<class unk>
16 void LIST<unk>::remove_front(){
17 if(_at_front == 0){
18 cout << "No List" << endl;
19 return;
20 }
21 NODE<unk> * tmp = _at_front;
22 down_size();
23 _at_front = tmp->next();
24 if(tmp->next() == NULL)
25 _at_end = 0; //need to clear _at_end as well once
you delete the last node
26
27
28 delete tmp;
29 return;
30 }
31


The code I'm working on currently is less fortunate. I created a
namespace for it


~~nodes.cpp

#include "nodes.h"
#include <iostream>
using namespace std;
template<class unk>
tree::NODE<unk>::NODE( unk states, NODE<unk> *cl, NODE<unk> *cr, NODE<unk>
*p ){
cout << "Im here" << endl;
}

template<class unk>
tree::NODE<unk>::~NODE<unk>(){
};
~~~~

|| g++ -Wall -ggdb -c nodes.cpp
nodes.cpp|5 col 1| error: ‘tree’ does not name a type
|| tree::NODE<unk>::NODE( unk states, NODE<unk> *cl, NODE<unk> *cr,
NODE<unk> *p ){
|| ^~~~
nodes.cpp|10 col 1| error: ‘tree’ does not name a type
|| tree::NODE<unk>::~NODE<unk>(){
|| ^~~~
make: *** [makefile|8| nodes.o] Error 1

before this, it was saying it couldn't find definitions of my templates
in this file. I did a circular thing and included, as per what it said
in the text,

#include node.cpp

in file node.h

/*
*
=====================================================================================
*
* Filename: nodes.h
*
* Description: description of phylogentic nodes as per
* Fitch and Sannkoff as describd by Felenstein
*
* Version: 1.0
* Created: Nov 4 21:15:49 EDT 2016
* Revision: none
* Compiler: gcc
*
* Author: Ruben Safir,
* Company: LIU Thesis
*
*
=====================================================================================
*/
#ifndef NODES_H
#define NODES_H
#include<iostream>
#include<string>
#include<vector>
#include "nodes.cpp"
namespace tree {


/*
==============================================================================
* Class NODE -
* Description - This is a node in the tree that must undergo parsimony
evaluation
*
================================================================================
*/


Now the namespace issue is cropping up.

Alf P. Steinbach

unread,
Nov 5, 2016, 1:54:00 PM11/5/16
to
On 05.11.2016 16:41, Popping mad wrote:
>
> I've been trying to create some custom system libraries with templating
> and it surprised me when I starting to get linking problems. Generally I
> create a .h file and a .cpp file and develop objects which can later be
> developed into shared libraries. Years ago I did quite a bit of work
> with C++ and libraries and I don't recall having this problem, but looking
> back at the code, I see I was cramming a lot of class definitions directly
> into the .h file. So I must have hit this snag before but I don't
> remember it.
[snip]
>
> Now the namespace issue is cropping up.
>

You don't have a namespace-related problem, or if you have one it's
unrelated.

The problem is simply that in order to instantiate a template with given
template arguments, the full textual definition must be available to the
compiler.

If you compile the template definitions separately, then you can only
instantiate them in the translation unit where you define them (because
here the textual definitions are available), and this means
instantiating them for a fixed number of possible types. They can be
used with these arguments in other TUs. But any other arguments, and the
linker will complain of lacking instantiations.

So usually templates are fully defined in headers.

E.g. much of Boost are template based header-only sub-libraries.


• • •

C++98 and C++03 had an `export` feature to deal with separate
compilation of template definitions.

Unfortunately, as I recall it was only ever implemented by Comeau and
(with an undocumented option to activate it) in the Intel compiler.

`export` was removed in C++11.

• • •

Rumours have long been that this will be fixed again “when” C++ gets
modules, and that's also rumoured to fix the extreme build times and
much else. E.g. Microsoft dismissed my suggestion of how to improve
build times because, hey, modules will fix all that. And Visual C++ does
have experimental module support already, but I don't know whether it
fixes build times, or deals with templates, or what.


Cheers & hth.,

- Alf

ruben safir

unread,
Nov 5, 2016, 2:49:31 PM11/5/16
to
On 11/05/2016 01:51 PM, Alf P. Steinbach wrote:
> translation unit


what is that...exactly.

Ben Bacarisse

unread,
Nov 5, 2016, 3:21:49 PM11/5/16
to
"The text of the program is kept in units called source files in this
International Standard. A source file together with all the headers
(17.6.1.2) and source files included (16.2) via the preprocessing
directive #include, less any source lines skipped by any of the
conditional inclusion (16.1) preprocessing directives, is called a
translation unit."

--
Ben.

Popping mad

unread,
Nov 5, 2016, 4:28:13 PM11/5/16
to
By this definition, I'm not understanding what Mr Steinbach is saying.
These files are connected by #includes and should be visible to each
other at compile time, and yet when a template is created in a namespace
in the .h file, that namespace is not even being translated as a namespace
scope in the .cpp file even when they are cross #included to each other.

I don't know what it is doing or why.

Paavo Helde

unread,
Nov 5, 2016, 5:52:29 PM11/5/16
to
On 5.11.2016 17:41, Popping mad wrote:
> The code I'm working on currently is less fortunate. I created a
> namespace for it
>
>
> ~~nodes.cpp
>
> #include "nodes.h"
> #include <iostream>
> using namespace std;
> template<class unk>
> tree::NODE<unk>::NODE( unk states, NODE<unk> *cl, NODE<unk> *cr, NODE<unk>
> *p ){
> cout << "Im here" << endl;
> }
>
> template<class unk>
> tree::NODE<unk>::~NODE<unk>(){
> };

> || g++ -Wall -ggdb -c nodes.cpp
> nodes.cpp|5 col 1| error: ‘tree’ does not name a type
> || tree::NODE<unk>::NODE( unk states, NODE<unk> *cl, NODE<unk> *cr,
> NODE<unk> *p ){
> || ^~~~

This is not a linker error.

Is the namespace called "tree"? If so, change this code to

#include "nodes.h"
#include <iostream>
using namespace std;

namespace tree {

template<class unk> NODE<unk>::NODE( unk states, NODE<unk> *cl,
NODE<unk> *cr, NODE<unk>
*p ){
cout << "Im here" << endl;
}

template<class unk>
};

}


Öö Tiib

unread,
Nov 5, 2016, 5:57:00 PM11/5/16
to
You are too much describing how you are confused with something and your
feelings about it and so too few what you expect and what really happens.
Perhaps you can make a minimal full example that really does behave in
unexpected manner for you?
0 new messages