模板,朋友,操作员..我们还需要玩得多么有趣? [英] Templates, friends, operators .. what more do we need to have fun?

查看:53
本文介绍了模板,朋友,操作员..我们还需要玩得多么有趣?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,


我想我已经遇到了一些经典的c ++陷阱,也许还有一些你可以帮我解决的问题。

对于我的项目,我需要使用矩阵和向量,所以我确定
决定自己实现它们。我知道已有

吨的矢量和矩阵实现,但我想要为我的需求提供

,而不需要调试某些人

别的代码。同时也变得有些个人化;-)。

计划:

- 定义一个矩阵< T>和矢量< T> class

- 让他们成为朋友直接执行某些操作 - 快速

和脏

- 定义运算符处理多个类型的实例

作为朋友


一段时间后,我学习了很多关于c ++语法的细微之处,我在前两步做了


现在链接器(我正在使用g ++ 3.3.4,没有任何开关引用

模板)唠叨抱怨不知道朋友

运营商我已经定义了。


让我们来看看细节:


我已将两个类分别定义为标题和< br $>
实现

和我的所有模板类我使用单个.cpp文件

包括

类模板实现,以显式实例化

专用类。


两个头文件(矩阵和向量)互相包含。它们包含

- 类模板的前向声明

- 运算符原型

- 类模板本身

- 包括对朋友类和朋友操作员的引用


操作符在相应的类实现文件中定义。


更多细节 - 我会举例说明:


Vector.h

===================== ============================= =================

....


#include" Grid2D.h"

#include" Matrix.h"


命名空间calcapp {


//模板方法

template< class T> void doWhateverywouvery(const T& v);


//类模板的前向声明

template< class T> class Vector;

template< class T> class Matrix;


//运算符原型

模板< class T>矩阵< T> operator /(const Vector< T>& v1,const

Vector< T>& v2);

....


//测试方法原型

模板< class T>矢量< T> doNothing(const Vector< T>& v);


模板< class T>

类Vector:public calcapp :: Grid2D< T> {

public:

template< class TF>朋友班Matrix;


Vector(int count_dim);

Vector(const Vector& other);


....

//张量产品

朋友Matrix< T>操作者/< T> (const Vector< T>& v1,const Vector< T>&

v2);

// dummy

friend Vector< T> doNothingInNS< T>(const Vector< T>& v);

受保护:

....

}; //类


} //名称空间


Vector.cpp

======== ========================================== ======== =========

#include" Vector.h"

....

名称空间calcapp {


模板< class T>

矩阵< T> calcapp :: operator /(const Vector< T>& v1,const Vector< T>& v2)

{


Matrix< T>结果(v1.size_x,v2.size_x);

....

返回结果;

} // tensorproduct

....

} //命名空间

TemplateInstances.cpp

=========== ======================================= =========== ======

#include" global.h"

#include" Vector.cpp"


命名空间calcapp {


模板类Grid2D< fptype> ;;


模板类Matrix< fptype> ;;

模板class Matrix< int32> ;;

模板类Matrix< int64> ;;


模板类Vector< fptype> ;;

模板类Vector< int32> ;;

模板类Vector< int64> ;;


}


test.cpp

============================================ ====== =================

....


Vector< fptype )v1(3),v2(3);

....


Matrix< fptype> M = v1 / v2;

Hello there,

I think I''ve run into some classic c++ pitfall and maybe some of
you guys can help me out.
For my project I will need to use matrices and vectors and so I
decided to implement them by myself. I know there are already
tons of vector and matrix implementations, but I wanted to have
one taylored for my needs and without debugging someones
else code. Also is''s become somewhat personal meanwhile ;-).

The plan :
- define a Matrix<T> and a Vector<T> class
- make them friends to perform some operations directly - quick
and dirty
- define the operators processing instances of more than one type
as friends

After a while and learning a lot about c++ syntax subtleness I made
the first two steps.
Now the linker (I''m using g++ 3.3.4 without any switches refering
templates) is nagging with complaints about not knowing the friend
operators I''ve defined.

Lets come to the details :

I''ve defined both classes separated into a header and the
implementation
and for all my template classes I''m using a single .cpp file which
includes
the class template implementations to explicitly instantiate the
specialized classes.

Both header files (matrix and vector) include each other. They contain
- the forward declarations of the class templates
- the operators prototypes
- the class template itself
- including the references to friend classes and friend operators

The operators are defined in the according class implementation files.

Some more details - I will show it exemplarily :

Vector.h
================================================== =================
....

#include "Grid2D.h"
#include "Matrix.h"

namespace calcapp {

//a template method
template <class T> void doWhateveryouwant(const T& v);

//forward declaration of class template
template <class T> class Vector;
template <class T> class Matrix;

//operator prototypes
template <class T> Matrix<T> operator/ (const Vector<T>& v1, const
Vector<T>& v2);
....

//prototype of a test-method
template <class T> Vector<T> doNothing(const Vector<T>& v);

template <class T>
class Vector : public calcapp::Grid2D<T> {
public:
template <class TF> friend class Matrix;

Vector(int count_dim);
Vector(const Vector & other);

....
//tensor product
friend Matrix<T> operator/<T> (const Vector<T>& v1, const Vector<T>&
v2);
//dummy
friend Vector<T> doNothingInNS<T>(const Vector<T>& v);
protected:
....
}; //class

} //namespace

Vector.cpp
================================================== =================
#include "Vector.h"

....
namespace calcapp {

template <class T>
Matrix<T> calcapp::operator/ (const Vector<T>& v1, const Vector<T>& v2)
{

Matrix<T> result(v1.size_x, v2.size_x);
....
return result;
} //tensorproduct
....
} //namespace
TemplateInstances.cpp
================================================== =================
#include "global.h"
#include "Vector.cpp"

namespace calcapp {

template class Grid2D<fptype>;

template class Matrix<fptype>;
template class Matrix<int32>;
template class Matrix<int64>;

template class Vector<fptype>;
template class Vector<int32>;
template class Vector<int64>;

}

test.cpp
================================================== =================
....

Vector<fptype) v1(3), v2(3);
....

Matrix<fptype> M = v1/v2;

此处编译器声明:
../ RunTest/test.cpp:310:对`calcapp :: Matrix< double>的未定义引用> calcapp :: operator /< double>(calcapp :: Vector< double> const&,calcapp :: Vector< double> const&)''


....

========================================== ======== =================

那么#!@ *是错的?这显然是一个链接器错误,对于我的理解,编译器没有为operator /< fptype>生成代码。

正确吗?


--------------------------

这个问题似乎并不存在运营商因为


....

v2 = calcapp :: doNothing(v1);

....


将导致同等的反应。

------------------------- -

甚至


....

int i = 10;

doWhateveryouwant( i);

....


不会编译(链接):未定义引用`void calcapp :: doWhateveryouwant< int>(int const&)''
and here the compiler states :
../RunTest/test.cpp:310: undefined reference to `calcapp::Matrix<double> >calcapp::operator/<double>(calcapp::Vector<double> const&, calcapp::Vector<double> const&)''
....
================================================== =================
So what the #!@* is wrong? That was obviously a linker error and for my
understanding the compiler didn''t generate code for operator/<fptype>.
Correct?

--------------------------
The problem doesn''t seem to be about operators because

....
v2 = calcapp::doNothing(v1);
....

would leed to an equivalent reaction.
--------------------------
And even

....
int i = 10;
doWhateveryouwant(i);
....

won''t compile (link) :undefined reference to `void calcapp::doWhateveryouwant<int>(int const&)''




因此它似乎与类或朋友无关。

但仍然不知何故联系人想出来了该功能已定义

命名空间calcapp



---------------- ----------


我是否必须明确表达你也实例化模板方法?我已经

到目前为止一无所知。怎么样?

运营商?


好​​的家伙,这是什么简单的伎俩? ;-)

再见,Micha



So it seems it has nothing to do with classes or friends either.
But still somehow the linker figured out that the function was defined
in
the namespace calcapp.
--------------------------

Do I have to explicitly instantiate template methods too? I''ve
read nothing about that so far. How??
Operators?

Ok guys, what''s the simple trick? ;-)
bye, Micha

推荐答案

Micha写道:
那你好,

我想我遇到了一些经典的c ++陷阱,也许有些人可以帮助我。
对于我的项目,我需要使用矩阵和向量等我决定自己实现它们。我知道已经有大量的矢量和矩阵实现,但是我想为我的需求做一个taylored并且没有调试某些人
其他代码。同时也变得有些个人化;-)。

计划:
- 定义一个矩阵< T>和矢量< T>上课
- 让他们的朋友直接进行一些操作 - 快速
和脏
- 定义操作员处理多种类型的实例


>过了一段时间,我学习了很多关于c ++语法的细微之处,我做了前两步。
现在链接器(我正在使用g ++ 3.3.4,没有任何开关引用
模板)抱怨不知道我已经定义的朋友
运营商。
Hello there,

I think I''ve run into some classic c++ pitfall and maybe some of
you guys can help me out.
For my project I will need to use matrices and vectors and so I
decided to implement them by myself. I know there are already
tons of vector and matrix implementations, but I wanted to have
one taylored for my needs and without debugging someones
else code. Also is''s become somewhat personal meanwhile ;-).

The plan :
- define a Matrix<T> and a Vector<T> class
- make them friends to perform some operations directly - quick
and dirty
- define the operators processing instances of more than one type
as friends

After a while and learning a lot about c++ syntax subtleness I made
the first two steps.
Now the linker (I''m using g++ 3.3.4 without any switches refering
templates) is nagging with complaints about not knowing the friend
operators I''ve defined.




说实话,我还没看完你的所有帖子(对于

我而言太长了,但您可能会关注常见问题解答。它至少描述了与你的症状相似的问题。

http://www.parashift.com/c++-faq-lit...html#faq-35.10


john



To be perfectly honest I haven''t read all your post (bit too long for
me) but you might care to check the FAQ. It does at least describe a
problem with similar symptoms to yours.

http://www.parashift.com/c++-faq-lit...html#faq-35.10

john


Micha写道:
你好,

我想我已经遇到了一些经典的c ++陷阱,也许有些人可以帮助我。
对于我的项目,我需要使用矩阵和向量,所以我决定通过以下方式实现它们我。我知道已经有大量的矢量和矩阵实现,但是我想为我的需求做一个taylored并且没有调试某些人
其他代码。同时也变得有些个人化;-)。

计划:
- 定义一个矩阵< T>和矢量< T>上课
- 让他们的朋友直接进行一些操作 - 快速
和脏
- 定义操作员处理多种类型的实例


>过了一段时间,我学习了很多关于c ++语法的细微之处,我做了前两步。
现在链接器(我正在使用g ++ 3.3.4,没有任何开关引用
模板)我抱怨不知道我已定义的朋友
运营商。

....
更多细节 - 我会举例说明:

Vector.h


首先,有一个名为vector.h的标题不是一个好主意。因为

系统中有一个(过时的)标题,包括

路径。通过用较少的
通用名称重命名来减少混淆似乎更安全。


Vector.cpp
======== ========================================== ======== =========
#include" Vector.h"

...命名空间calcapp {

模板< T类>
矩阵< T> calcapp :: operator /(const Vector< T>& v1,const Vector< T>& v2)


Matrix< T>结果(v1.size_x,v2.size_x);
...
返回结果;
} // tensorproduct
...
} //命名空间

TemplateInstances.cpp


看起来这个模板函数是在源文件中定义的。

模板定义需要放在头文件,所以编译器

将在编译源代码之前看到模板定义

实例化模板。使用

源文件中的模板定义,它只能有效地用于此

文件中的其他例程。

#包括global.h
#include" Vector.cpp"
名称空间calcapp {

模板类Grid2D< fptype> ;;

模板类Matrix< fptype> ;;
模板类Matrix< int32> ;;
模板类Matrix< int64> ;;

模板类Vector< fptype> ;;
模板类Vector< int32> ;;
模板类Vector< int64> ;;

}

test.cpp
======= =========================================== ======= ==========
......

Vector< fptype)v1(3),v2(3);
......

矩阵< fptype> M = v1 / v2;
Hello there,

I think I''ve run into some classic c++ pitfall and maybe some of
you guys can help me out.
For my project I will need to use matrices and vectors and so I
decided to implement them by myself. I know there are already
tons of vector and matrix implementations, but I wanted to have
one taylored for my needs and without debugging someones
else code. Also is''s become somewhat personal meanwhile ;-).

The plan :
- define a Matrix<T> and a Vector<T> class
- make them friends to perform some operations directly - quick
and dirty
- define the operators processing instances of more than one type
as friends

After a while and learning a lot about c++ syntax subtleness I made
the first two steps.
Now the linker (I''m using g++ 3.3.4 without any switches refering
templates) is nagging with complaints about not knowing the friend
operators I''ve defined.
....
Some more details - I will show it exemplarily :

Vector.h
First it''s a not a good idea to have a header called "vector.h" since
there is an (obsolete) header with the same name in the system include
paths. It seems safer to minimize confusio by renaming it with a less
generic name.


Vector.cpp
================================================== =================
#include "Vector.h"

...
namespace calcapp {

template <class T>
Matrix<T> calcapp::operator/ (const Vector<T>& v1, const Vector<T>& v2)
{

Matrix<T> result(v1.size_x, v2.size_x);
...
return result;
} //tensorproduct
...
} //namespace
TemplateInstances.cpp
It looks like this template function is being defined in a source file.
Template definitions need to be placed in header files so the compiler
will have seen the template defnition before it compiles source code
that instantiates the template. With the template definition in a
source file, it is effectively available only to other routines in this
file which come after it.
#include "global.h"
#include "Vector.cpp"

namespace calcapp {

template class Grid2D<fptype>;

template class Matrix<fptype>;
template class Matrix<int32>;
template class Matrix<int64>;

template class Vector<fptype>;
template class Vector<int32>;
template class Vector<int64>;

}

test.cpp
================================================== =================
...

Vector<fptype) v1(3), v2(3);
...

Matrix<fptype> M = v1/v2;
此处编译器声明:
../ RunTest/test.cpp:310:对`calcapp :: Matrix< double>的未定义引用> calcapp :: operator /< double>(calcapp :: Vector< double> const&,calcapp :: Vector< double> const&)''
and here the compiler states :
../RunTest/test.cpp:310: undefined reference to `calcapp::Matrix<double> >calcapp::operator/<double>(calcapp::Vector<double> const&, calcapp::Vector<double> const&)''



... < br => =============================================== === =================
那么#!@ *是错的?这显然是一个链接器错误,并且我理解编译器没有为operator /< fptype>生成代码。
正确吗?



...
================================================== =================
So what the #!@* is wrong? That was obviously a linker error and for my
understanding the compiler didn''t generate code for operator/<fptype>.
Correct?




编译test.cpp时,编译器没有看到

的定义,当它到达引用它的第310行时。

没有定义手,编译器不知道什么代码要生成b
。编译器也不记住模板定义从

一个源文件到下一个。实例化

模板的每个源文件必须确保在编译时自己的代码之前包含模板定义




解决方案是将运算符/模板和任何其他模板

定义移动到一个头文件中,test.cpp和这些

模板类的其他客户端将会包括。


Greg



When compiling test.cpp, the compiler did not see the definition for
the operator/ by the time it reached line 310 that references it.
Without a definition on hand, the compiler does not know what code to
generate. Nor does the compiler "remember" template definitions from
one source file to the next. Every source file that instantiates a
template must ensure that the the template definition is included
before its own code when it is compiled.

The solution is to move the operator/ template and any other template
definitions into a header file that test.cpp and other clients of these
template classes will then include.

Greg


>
它看起来像这个模板功能正在源文件中定义。
模板定义需要放在头文件中,这样编译器在编译实例化模板的源代码之前就会看到模板定义。使用
源文件中的模板定义,它只能有效地用于此
文件中的其他例程。

It looks like this template function is being defined in a source file.
Template definitions need to be placed in header files so the compiler
will have seen the template defnition before it compiles source code
that instantiates the template. With the template definition in a
source file, it is effectively available only to other routines in this
file which come after it.

#包括global.h
#include" Vector.cpp"
#include "global.h"
#include "Vector.cpp"




格雷格,你错过了他写的#include" Vector.cpp" ;.为什么有些人

坚持将模板代码放在cpp文件中,然后拉各种各样的

的技巧来弥补这一点超出了我。


john



Greg, you missed that he wrote #include "Vector.cpp". Why some people
insist on putting template code in cpp files and then pulling all sorts
of tricks to compensate for this is beyond me.

john


这篇关于模板,朋友,操作员..我们还需要玩得多么有趣?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆