でfoo.h
:
#ifndef FOO_H
#define FOO_H
enum Rat
{
A,
B
};
class Foo
{
public:
template<Rat r>
int aMemberFunc(int, int, int);
};
#endif
でfoo.cpp
:
#include "foo.h"
namespace {
template<Rat r>
int helper(int a, int b)
{
return a+b*((int) r);
}
}
template<Rat r>
int Foo::aMemberFunc(int a, int b, int c)
{
return a + helper<r>(b,c);
}
でmain.cpp
:
#include "foo.h"
#include <iostream>
using namespace std;
int main(void)
{
Foo test;
cout << test.aMemberFunc<B>(1,2,3) << endl;
}
でコンパイルするとg++ main.cpp foo.cpp
、次のようになります。
main.cpp:(.text+0x88): undefined reference to `int Foo::aMemberFunc<(Rat)1>(int, int, int)'
collect2: ld returned 1 exit status
ヘルパーと多くの荷物を持ってくるので、ヘッダーに物を移動したくないので、ファイルを追加しようとしましたfooimpl.cpp
:
#include "foo.h"
#include "foo.cpp"
template int Foo::aMemberFunc<A>(int,int,int);
template int Foo::aMemberFunc<B>(int,int,int);
そして、コンパイルしますg++ fooimpl.cpp main.cpp foo.cpp
これは Dietmar の提案によるものでした (ありがとう!) がvoid rand();
、ヘッダーfoo.h
と上記のトリックに関数を追加するとすぐに、次のエラーが発生しますvoid rand() {}
。foo.cpp
foo.cpp:(.text+0x0): `Foo::rand()' の複数定義 /tmp/ccoCtGMk.o:fooimpl.cpp:(.text+0x0): 最初にここで定義
これを回避するにはどうすればよいですか?