r****t 发帖数: 10904 | 1 说是 undefined reference error. No way 啊。。。
昨天看了一个晚上了,哪位能行个好,帮忙看看错在哪? 搞定了发包子(还得学学怎
么发)虽然俺好像挺穷的。
把其他不相关的东西都去掉了,就这么点 code, 怎么看都看不出该怎么改,附件下载
就是一个 cxx file. g++ -o main main.cxx 就行。
code 也贴在下面:
main.cxx |
r****t 发帖数: 10904 | 2 把 error message 也贴一下:
g++ -Wall main.o -o main
main.o: In function `void M::Location::read >(char
const*, SArray::Array&) const':
main.cxx:(.text._ZNK1M8Location4readIN6SArray5ArrayIfLj3EEEEEvPKcRT_[void M:
3u>&) const]+0x1b): undefined reference to `void M::read
float, 3u> >(M::Location const&, char const*, SArray::Array&)'
main.o: In function `void M::read_matrix >(char
const*, char const*, SArray::Array |
a**a 发帖数: 416 | 3 where is your definition for Location::Location()?
【在 r****t 的大作中提到】 : 说是 undefined reference error. No way 啊。。。 : 昨天看了一个晚上了,哪位能行个好,帮忙看看错在哪? 搞定了发包子(还得学学怎 : 么发)虽然俺好像挺穷的。 : 把其他不相关的东西都去掉了,就这么点 code, 怎么看都看不出该怎么改,附件下载 : 就是一个 cxx file. g++ -o main main.cxx 就行。 : code 也贴在下面: : main.cxx
|
r****t 发帖数: 10904 | 4 I missed it...
in the declaration, I have to add:
class Location {
public:
Location();
Location(const char *name);
...
};
Location::Location() {}
Location::Location(const char *name) {}
【在 a**a 的大作中提到】 : where is your definition for Location::Location()?
|
t****t 发帖数: 6806 | 5 除了这个之外,
把
template
void
read(const Location &location, const char *dataset_name, SArray::
Array & arr) {} // this function is not found
移到
class Location
上面
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
先声明再使用!先声明再使用!先声明再使用!
//重复100遍
【在 r****t 的大作中提到】 : I missed it... : in the declaration, I have to add: : class Location { : public: : Location(); : Location(const char *name); : ... : }; : Location::Location() {} : Location::Location(const char *name) {}
|
t****t 发帖数: 6806 | |
p****s 发帖数: 32405 | 7 只有30遍
【在 t****t 的大作中提到】 : 包子拿来.
|
r****t 发帖数: 10904 | 8 那我完了,写这 code 的人明显是想利用这个特性,
// this function is not found
template
void read(const Location &location, const char *dataset_name,
SArray::Array & arr) {}
是 intend to be written later 的。我试试在头文件里面先 include 这部分看看。
。。得到下午才能试了。
【在 t****t 的大作中提到】 : 除了这个之外, : 把 : template : void : read(const Location &location, const char *dataset_name, SArray:: : Array & arr) {} // this function is not found : 移到 : class Location : 上面 : 先声明再使用!先声明再使用!先声明再使用!
|
t****t 发帖数: 6806 | 9 这种特性正常的做法是依靠class specialization或class partial specialization,
因为函数是不能specialize的, 函数依靠的是overload.
如果可以先声明的话, 也不是不可以, 但是你可能会需要做explicit instantiation,
要不然还是link error. template的声明和定义分开就是比较麻烦: 在使用的时候只看
到了声明, 那就不会implicit instantiation, 编译器就认为这东西在别处
instantiate过了.
如果使用者是个template(如你这种情况), 其实还好, 只要在使用这个template以前把
定义提供好就行了.
【在 r****t 的大作中提到】 : 那我完了,写这 code 的人明显是想利用这个特性, : // this function is not found : template : void read(const Location &location, const char *dataset_name, : SArray::Array & arr) {} : 是 intend to be written later 的。我试试在头文件里面先 include 这部分看看。 : 。。得到下午才能试了。
|
r****t 发帖数: 10904 | 10 template的声明和定义分开,是不是说像下面这样? linking 好像没出错。我没有用
explicit instantiation 吧? 头文件有点多,include 挺乱,不好保证 reference 到以前有定义。。
namespace SArray {
template class Array;
template
class Array
{
public:
Array() {}
};
}
namespace M {
class Location;
// first arg has to be "const" Location &
template
void read(const Location &, const char * dataset_name, T & matrix);
cl
【在 t****t 的大作中提到】 : 这种特性正常的做法是依靠class specialization或class partial specialization, : 因为函数是不能specialize的, 函数依靠的是overload. : 如果可以先声明的话, 也不是不可以, 但是你可能会需要做explicit instantiation, : 要不然还是link error. template的声明和定义分开就是比较麻烦: 在使用的时候只看 : 到了声明, 那就不会implicit instantiation, 编译器就认为这东西在别处 : instantiate过了. : 如果使用者是个template(如你这种情况), 其实还好, 只要在使用这个template以前把 : 定义提供好就行了.
|
|
|
r*********r 发帖数: 3195 | 11 我觉得是 M::read 函数的第三个参数的 type 有错误,所以不能instantiate.
改成 T& arr 就可以了. |
z***e 发帖数: 5393 | 12 嗯,我觉得也是。
lz 的两个read() function是完全不同的:
template
void read(const Location &, const char * dataset_name, T & matrix);
//这个declare了,但是下面并不是definition. 第三个参数类型都不同。
template
void
read(const Location &location, const char *dataset_name, SArray::
Array & arr) {} // this function is not found
}
然后lz:
Array arr;
M::read_matrix("file", "location", arr);
arr是Array---这个就是你的type,相当于:
void read(const Location &, const char * dataset_name, Array &
mat
【在 r*********r 的大作中提到】 : 我觉得是 M::read 函数的第三个参数的 type 有错误,所以不能instantiate. : 改成 T& arr 就可以了.
|
r****t 发帖数: 10904 | 13 你说的没错,这其实也是先 supply definition before calling.
我的问题就是不知道
1. 如何把 template function 的 declare 和 definition 分开。
or,
2. 如何 overload template function (function template?)
【在 z***e 的大作中提到】 : 嗯,我觉得也是。 : lz 的两个read() function是完全不同的: : template : void read(const Location &, const char * dataset_name, T & matrix); : //这个declare了,但是下面并不是definition. 第三个参数类型都不同。 : template : void : read(const Location &location, const char *dataset_name, SArray:: : Array & arr) {} // this function is not found : }
|
z***e 发帖数: 5393 | 14 可以分开啊,比如:
#include
#include
using namespace std;
template
void write(T);
template
void test(T parameter)
{
write(parameter);
}
int main()
{
test(1);
test("adbsdfs");
return 1;
}
template
void write(T a)
{
std::cout<
}
关键是compiler在instantialize你的template的时候,会好像#define一样展开,你的
code里面的两个Read(一个declare,一个definition),展开后是不同的两个东西,所
以当然会说第一个Read找不到definition了。
template本身就是overload啊,还要怎么overload?
【在 r****t 的大作中提到】 : 你说的没错,这其实也是先 supply definition before calling. : 我的问题就是不知道 : 1. 如何把 template function 的 declare 和 definition 分开。 : or, : 2. 如何 overload template function (function template?)
|
r****t 发帖数: 10904 | 15 我刚才试了一下,如果先 supply 两个 function template definition before definition of class Location, 这个使用 (M::read_matrix("file", "location", arr);) 总是 instantiate 第二个,而不是第一个 function.
应该是 g++ 用了 partial ordering of function templates, 可是 google 了一下没找到。
【在 z***e 的大作中提到】 : 嗯,我觉得也是。 : lz 的两个read() function是完全不同的: : template : void read(const Location &, const char * dataset_name, T & matrix); : //这个declare了,但是下面并不是definition. 第三个参数类型都不同。 : template : void : read(const Location &location, const char *dataset_name, SArray:: : Array & arr) {} // this function is not found : }
|
r****t 发帖数: 10904 | 16 你都说了两个 M::read 不一样,我就是想 instantiate 第二个 definition,应该还是
叫 overload 吧?
你的这个例子里面,你试试加个第二个
template
void write(Array a){};
就是我上面那个例子了。
【在 z***e 的大作中提到】 : 可以分开啊,比如: : #include : #include : using namespace std; : template : void write(T); : template : void test(T parameter) : { : write(parameter);
|
r*********r 发帖数: 3195 | 17 c++ 的type inference 机制比ml 弱, 没有类似 pattern match的东西,
所以你原来的code 不能被 instantiate。就这么简单。 |
z***e 发帖数: 5393 | 18 你可以这样try try:
write>(...)
就是显式地表明T是什么东西,可能就行了。
还是
【在 r****t 的大作中提到】 : 你都说了两个 M::read 不一样,我就是想 instantiate 第二个 definition,应该还是 : 叫 overload 吧? : 你的这个例子里面,你试试加个第二个 : template : void write(Array a){}; : 就是我上面那个例子了。
|
t****t 发帖数: 6806 | 19 分开没有问题, 但是引用之前先声明是最最基本的规则, 一定不能忘了
函数没有specialization, 所以每个需要specialize的case都需要先声明, 跟class不
一样, 声明最general那个就算声明了(其实class的specialization也是需要先声明
再使用的, 但是由于dependent name的存在, 这个时间可以推后)
template function的overload和普通函数的overload没有什么区别
partial ordering of function template看这里
http://cs.calvin.edu/books/c++/C++Standard-Nov97/template.html#temp.func.order
(要学会效使用google)
【在 r****t 的大作中提到】 : 你说的没错,这其实也是先 supply definition before calling. : 我的问题就是不知道 : 1. 如何把 template function 的 declare 和 definition 分开。 : or, : 2. 如何 overload template function (function template?)
|
r****t 发帖数: 10904 | 20 你来这个 specialization,俺这种外行一下子不太懂,具体来说我的 situation 是:
M::Location::read 引用 M::read, (note it 把 Location object itself 传给 M::read)
=> declaration of M::read 定要先于 Definition M::Location::read 。
但是在没简化的 code 里面, the definition of M::read references some
overloaded M::Location::read (不难猜到这个因为 Location object itself is
passed to M::read )
=> declaration of M::Location::read 定要先于 definition of M::read.
综合上面两点,我只好把两个 template function 的 declaration 和 definition 分
开到两处,我甚至读到一些 webpage 说 g++ "basically
【在 t****t 的大作中提到】 : 分开没有问题, 但是引用之前先声明是最最基本的规则, 一定不能忘了 : 函数没有specialization, 所以每个需要specialize的case都需要先声明, 跟class不 : 一样, 声明最general那个就算声明了(其实class的specialization也是需要先声明 : 再使用的, 但是由于dependent name的存在, 这个时间可以推后) : template function的overload和普通函数的overload没有什么区别 : partial ordering of function template看这里 : http://cs.calvin.edu/books/c++/C++Standard-Nov97/template.html#temp.func.order : (要学会效使用google)
|
|
|
r****t 发帖数: 10904 | 21 虽然我手里现在没有 gcc-2.95, 但是从我以前 compile 这个 code 的经验,在 gcc-2
.95 下面是这样是可以 compile 和运行的。
【在 r*********r 的大作中提到】 : c++ 的type inference 机制比ml 弱, 没有类似 pattern match的东西, : 所以你原来的code 不能被 instantiate。就这么简单。
|
t****t 发帖数: 6806 | 22 我知道原作者的意思.
他提供一个通用的read(location, dataset_name, matrix), 然后针对不同类型的
matrix
提供不同版本的read.
如果用function overload, 那在用到不同版本之前, 就必须先声明. 定义可以拖后.
g++把声明和定义分开没有问题, 在最后实现instantiation时, 定义必须available.
instantiation就是最后所有的type都决定了的时候那个调用.
g++的partial ordering of function template支持也没有问题(至少我用的时候没有
问题).
【在 r****t 的大作中提到】 : 你来这个 specialization,俺这种外行一下子不太懂,具体来说我的 situation 是: : M::Location::read 引用 M::read, (note it 把 Location object itself 传给 M::read) : => declaration of M::read 定要先于 Definition M::Location::read 。 : 但是在没简化的 code 里面, the definition of M::read references some : overloaded M::Location::read (不难猜到这个因为 Location object itself is : passed to M::read ) : => declaration of M::Location::read 定要先于 definition of M::read. : 综合上面两点,我只好把两个 template function 的 declaration 和 definition 分 : 开到两处,我甚至读到一些 webpage 说 g++ "basically
|
r****t 发帖数: 10904 | 23
对,他就是这个目的。
按这个办法搞定了,只是有些 cpp 文件在最后还要来 #include 一个 header, 感觉不
是很正规。。。
【在 t****t 的大作中提到】 : 我知道原作者的意思. : 他提供一个通用的read(location, dataset_name, matrix), 然后针对不同类型的 : matrix : 提供不同版本的read. : 如果用function overload, 那在用到不同版本之前, 就必须先声明. 定义可以拖后. : g++把声明和定义分开没有问题, 在最后实现instantiation时, 定义必须available. : instantiation就是最后所有的type都决定了的时候那个调用. : g++的partial ordering of function template支持也没有问题(至少我用的时候没有 : 问题).
|
r****t 发帖数: 10904 | |