C++ 如何在不将所有相关代码带到标头的情况下解析模板成员函数的此未定义引用?

C++ 如何在不将所有相关代码带到标头的情况下解析模板成员函数的此未定义引用?,c++,templates,C++,Templates,在foo.h中: #ifndef FOO_H #define FOO_H enum Rat { A, B }; class Foo { public: template<Rat r> int aMemberFunc(int, int, int); }; #endif 在main.cpp中: #include "foo.h" namespace { template<Rat r> int helper(int a, int b) {

foo.h
中:

#ifndef FOO_H
#define FOO_H

enum Rat
{
    A,
    B
};

class Foo
{
public:
    template<Rat r>
    int aMemberFunc(int, int, int);
};

#endif
main.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);
}
#include "foo.h"
#include <iostream>

using namespace std;

int main(void)
{
    Foo test;
    cout << test.aMemberFunc<B>(1,2,3) << endl;
}
#include "foo.h"
#include "foo.cpp"

template int Foo::aMemberFunc<A>(int,int,int);
template int Foo::aMemberFunc<B>(int,int,int);
我不希望将内容移动到标题,因为这会带来助手和很多行李,我尝试添加一个文件
fooimpl.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);
}
#include "foo.h"
#include <iostream>

using namespace std;

int main(void)
{
    Foo test;
    cout << test.aMemberFunc<B>(1,2,3) << endl;
}
#include "foo.h"
#include "foo.cpp"

template int Foo::aMemberFunc<A>(int,int,int);
template int Foo::aMemberFunc<B>(int,int,int);
#包括“foo.h”
#包括“foo.cpp”
模板intfoo::aMemberFunc(int,int,int);
模板intfoo::aMemberFunc(int,int,int);
然后使用
g++fooimpl.cpp main.cpp foo.cpp编译

这是根据Dietmar的建议(谢谢!),但只要我添加一个函数
void rand()foo.h
的标题中的code>和
void rand(){}
foo.cpp
中的

foo.cpp:(.text+0x0):'foo::rand()的多个定义 /tmp/ccoCtGMk.o:fooimpl.cpp:(.text+0x0):首先在这里定义


如何解决这个问题?

您需要实例化您的函数,而不是专门化它:

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

template int Foo::aMemberFunc<A>(int,int,int);
template int Foo::aMemberFunc<B>(int,int,int);
#包括“foo.h”
#包括“foo.cpp”
模板intfoo::aMemberFunc(int,int,int);
模板intfoo::aMemberFunc(int,int,int);

不幸的是,您称之为“实例化”,标准称之为“专门化”;-)@KerrekSB:根据14.7.2[临时显式]第1段,我显式地实例化了一个专门化。@DietmarKühl感谢编译的,但是我把这个问题编辑成了现实生活中的一个例子:Foo实际上还有其他正常的函数,在这种情况下,above技巧给了我另一个编译器错误,我似乎无法回避…@DietmarKühl nvm我去掉了impl,将模板的安装扔进了.C,这就完成了这个技巧,谢谢!