我有这段代码:
template<typename T>
class Listoid{
private:
std::vector<T> list;
public:
typedef typename std::vector<T>::iterator iterator;
iterator begin() {return list.begin();}
iterator end() {return list.end();}
public:
Listoid(T t) {
list.push_back(t);
}
const T operator [](int i){
return list[i];
}
void addElem(T ne){
list.push_back(ne);
}
friend T cons(T new_elem, Listoid<T> list);
};
template<typename T>
Listoid<T> cons(T new_elem, Listoid<T> list){
Listoid<T> new_list(new_elem);
for(typename Listoid<T>::iterator it = list.begin(), e = list.end();
it != e; ++it){
new_list.addElem(*it);
}
return new_list;
}
int main(){
Listoid<int> lista(312);
lista.addElem(22);
Listoid<int> lista2 = cons(21, lista);
return EXIT_SUCCESS;
}
但是我无法编译它;我收到以下错误:
/tmp/listoid-3kYCmd.o: In function `main':
listoid.cpp:(.text+0xda): undefined reference to `cons(int, Listoid<int>)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
也许这很简单,但我无法解决。有人可以帮忙吗?
答案 0 :(得分:5)
您必须告诉编译器cons
是函数模板而不是简单函数。使用以下语法:
friend T cons <>(T new_elem, Listoid<T> list);
注意功能名称后的&lt;&gt; 。
否则它正在搜索简单的功能,而不是功能模板。这是链接器告诉你的。
[UPDATE]
并且不要忘记在其朋友班之前添加你的函数的前向声明,这样你的班级就会知道什么是朋友。
template<typename T>
Listoid<T> cons(T new_elem, Listoid<T> list);
[UPDATE2]
并更改您的功能模板类型,并添加您的课程的前向声明。 参见:
template<typename T>
class Listoid;
template<typename T>
Listoid<T> cons(T new_elem, Listoid<T> list);
template<typename T>
class Listoid{
...
friend Listoid<T> cons <>(T new_elem, Listoid<T> list);
};
这对我有用:ideone
答案 1 :(得分:1)
friend T cons(T new_elem, Listoid<T> list);
不是模板,后来的template<typename T> Listoid<T> cons(T new_elem, Listoid<T> list)
是cons()
函数的不同重载。请参阅FAQ。
答案 2 :(得分:1)
尝试使用模板声明和正确的返回类型重新处理函数声明:
template<typename U> friend Listoid<U> cons(U new_elem, Listoid<U> list);
并重命名您的typename
,以便它不会影响您的班级模板中的模板类型。
答案 3 :(得分:1)
问题是你有两个不同的cons
声明,一个在friend
声明中,另一个声明在命名空间级别。模板中的友谊并不像开头那样简单,我建议您阅读this其他答案并详细解释不同的选项。特别是,如果您希望(似乎)只与模板的特定专业化成交朋友,则需要在类模板之前提前声明:
template<typename T>
class Listoid;
template<typename T>
T cons(T new_elem, Listoid<T> list);
template<typename T>
class Listoid{
friend T cons<T>(T,Listoid<T>);
...
在当前表单中,您声明非模板函数是朋友。非模板函数将比模板更好地匹配(当模型匹配时,非模板优先于模板),编译器将生成对非teplated函数的依赖:
int const(int,Listoid<int>);