1

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): 最初にここで定義

これを回避するにはどうすればよいですか?

4

1 に答える 1

2

関数を特殊化するのではなく、インスタンス化する必要があります。

#include "foo.h"
#include "foo.cpp"

template int Foo::aMemberFunc<A>(int,int,int);
template int Foo::aMemberFunc<B>(int,int,int);
于 2012-10-24T23:32:39.907 に答える