Template Specialization and Libraries

Here's my code:

read.h:
1
2
3
4
5
6
7
8
#include "parse.h"
#include <string>

template<typename T>
void readValue(const std::string& str, T& value)
{
	parse(str, value);
}


parse.h:
 

#include <sstream>
#include <string>
#include <iostream>

template<typename T>
void parse(const std::string& str, T& value)
{
std::cout << "Parsing other" << std::endl;
std::istringstream is(str);
is >> value;
}


parse.cpp:
 

#include "parse.h"
#include <stdint.h>
#include <iostream>

template<>
void parse<int8_t>(const std::string& str, int8_t& value)
{
std::cout << "Parsing int8_t" << std::endl;
int dummy;
parse(str, dummy);
value = int8_t(dummy);
}


testTemplates.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "read.h"
#include <iostream>
#include <string>
#include <stdint.h>

int main()
{
	int a;
	int8_t b;


	std::string aStr("10000");
	std::string bStr("15");

	readValue(aStr, a);
	readValue(bStr, b);

	std::cout << a << "  " << int(b) << std::endl;
}



Here is my Makefile:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
all : testTemplates

#PARSE_OBJ := libParse.a
PARSE_OBJ := parse.o

testTemplates : testTemplates.o $(PARSE_OBJ)
	g++ -std=c++0x -o $@ $^

libParse.a : parse.o
	ar rcs $@ $^

parse.o : parse.cpp parse.h
	g++ -std=c++0x -o $@ -c $<

testTemplates.o : testTemplates.cpp parse.h read.h
	g++ -std=c++0x -o $@ -c $<

clean :
	rm -f testTemplates
	rm -f libParse.a
	rm -f *.o 


Question:
If I link testTemplates.o to parse.o, I get the template specialization code declared in parse.cpp. If I put parse.o into a library first (by changing teh value of PARSE_OBJ) and then link testTemplates.o to the library, I lose the template specialization code in parse.o, and end up calling the general template code in parse.h.

I would like the template specialization code to be called in both cases. What am I missing to force the code from read.h (compiled as part of testTemplates.o) to link to the correct function in the library?

By the way, I am stuck using gcc 4.4.3, thus the -std=c++0x.
See: http://www.gotw.ca/publications/mill17.htm

read.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "parse.h" 
// parse.h has the declaration for the function 
// void read_int8_value( const std::string& str, std::int8_t& value ) ;
// and these two #includes 
#include <string>
#include <cstdint>

template < typename T > struct readValue_helper
{
    static void readValue( const std::string& str, T& value ) { parse(str, value); }
};

template <> struct readValue_helper<std::int8_t>
{
    static void readValue( const std::string& str, std::int8_t& value )
    {  read_int8_value( str, value ) ; }
};

template < typename T >
void readValue( const std::string& str, T& value ) 
{ readValue_helper<T>::readValue( str, value ) ; }


parse.cpp
1
2
3
4
5
6
7
8
9
10
#include "parse.h" 

void read_int8_value( const std::string& str, std::int8_t& value )
{
        int dummy ;
        parse(str, dummy);
        value = dummy ;
}

// ... 
Topic archived. No new replies allowed.