lib.h:
#include <iostream>
namespace lib {
template <class T>
void f(T t)
{
std::cout << "lib f " << t << std::endl;
}
}
客户端.cpp:
#include "lib.h"
// explicit instantiation
template
void lib::f(char);
int main()
{
lib::f('x');
}
libmock.h:
#include <iostream>
#include "lib.h"
namespace lib {
template <>
void f(char c)
{
std::cout << "libmock f " << c << std::endl;
}
}
生成文件:
run: prod test
./prod
./test
prod: client.o
${CXX} -o $@ $^
test: client.o libmock.o
${CXX} -o $@ $^
clean:
-rm *.o prod test
使用 GCC 4.3.2(以及“IBM XL C/C++ for AIX, V11.1 (5724-X13)”),我得到了我期望的结果:
$ make
g++ -c -o client.o client.cpp
g++ -o prod client.o
g++ -c -o libmock.o libmock.cpp
g++ -o test client.o libmock.o
./prod
lib f x
./test
libmock f x
也就是说,我通过将新功能与提供比库提供的功能模板更专业的功能模板的对象链接,将新功能注入客户端。
但是,如果我使用“CC: Sun C++ 5.12 SunOS_sparc Patch 148506-14 2013/09/24”,则会收到以下错误:
$ CXX=CC make
CC -c -o client.o client.cpp
CC -o prod client.o
CC -c -o libmock.o libmock.cpp
CC -o test client.o libmock.o
ld: fatal: symbol 'void lib::f<char>(__type_0)' is multiply-defined:
(file client.o type=FUNC; file libmock.o type=FUNC);
Makefile:9: recipe for target 'test' failed
make: *** [test] Error 2
我的解决方案必须适用于所有这三个编译器。我只是对 GCC 和 AIX 中的一些未定义行为感到幸运吗?我可以将一些选项传递给 Sun 编译器以使其工作吗?我正在尝试做的事情是否表明我没有完全理解这些模板概念?请赐教!