我正在尝试在普通类上实现朋友模板功能。
fren.h
#include <iostream>
namespace sn{
class Fren{
private:
int x;
public:
Fren(int y):x(y){
}
template<typename B>
friend void getValue(B& asd);
};
template<typename B>
void getValue(B& asd);
}
fren.cpp
#include "fren.h"
namespace sn{
template<typename B>
void getValue(B& asd){
std::cout<<asd.x<<std::endl;
}
}
的main.cpp
#include "fren.h"
int main() {
sn::Fren f(10);
sn::getValue(f);
return 0;
}
我想获得Fren的私人价值x。
但是我得到了“未定义的引用”错误。
答案 0 :(得分:2)
首先,除非有其他原因,否则大多数属于单个头文件。有关原因,请参阅"Why can templates only be implemented in the header file?"。
也就是说,如果要对函数模板使用显式实例化,则可以。请注意以下内容,这也比您的朋友更具限制性。此代码仅与具有匹配Fren
的模板参数的函数模板相关联:
<强> func.h 强>
#ifndef SAMPLE_FUNC_H
#define SAMPLE_FUNC_H
namespace sn
{
template<class T>
struct Fren;
template<class T>
void getValue(const Fren<T>& s);
template<class T>
struct Fren
{
friend void getValue <>(const Fren<T>&);
Fren() : x(42) {}
private:
int x;
};
} // namespace
#endif
<强> func.cpp 强>
#include "func.h"
#include <iostream>
namespace sn
{
template<class T>
void getValue(const Fren<T>& s)
{
std::cout << s.x << ':' << __PRETTY_FUNCTION__ << '\n';
}
// explicit instantiation here
template void getValue <int> (const Fren<int>&);
}
<强>的main.cpp 强>
#include <iostream>
#include <string>
#include "func.h"
int main()
{
sn::Fren<int> s;
sn::getValue(s);
}
<强>输出强>
42:void sn::func(const S<T> &) [T = int]
使用Apple LLVM版本6.1.0(clang-602.0.53)编译(基于LLVM 3.6.0svn)
简而言之,您的代码似乎缺少实际的显式实例化。