意外的模板行为 [英] unexpected template behavior

查看:56
本文介绍了意外的模板行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板类,当我使用< int>,

实现它时工作正常但是当我使用< floator< doubleit不起作用时。该类有一个类型为T的动态数组,可以在我的构造函数中实例化。当

类型T为int时,数组的工作方式与我预期的一样。但是当我使用double或

float时,数组指向垃圾和数组元素的任何更新

没有区别。


我在XP专业版机器上使用Visual Studio 2005。以下是

给我带来问题的代码。如果有人可以帮忙解释一下是什么,我错了,为什么这不行,我真的很感激。

提前谢谢。

模板< class T>

class Tuple

{

public:

元组< T>(无效);

元组< T>(T x,T y);

~元组< T>(无效);


T getX();

T getY();


void setX(T x);

void setY(T y);

private:

T * _values; // arrray of values

};


模板< class T>

元组< T> ::元组(void )

{

_values = new T [2];

_values [0] = 0;

_values [1] = 0;

}


模板< class T>

元组< T> ::元组(T x,T y)

{

_values = new T [2];

_values [0] = x;

_values [1] = y;

}


模板< class T>

元组< T>: :〜元组(无效)

{

}


模板< class T>

T Tuple< T> :: getX(){return _values [0]; }


模板< class T>

T Tuple< T> :: getY(){return _values [1]; }


模板< class T>

void Tuple< T> :: setX(T x){_ value [0] = x; }


模板< class T>

void Tuple< T> :: setY(T y){_ value [1] = y; }

解决方案


ho ******************** @ gmail.com 写道:
< blockquote class =post_quotes>
我有一个模板类,当我使用< int>,

实现它时工作正常但是当我使用< floator< doubleit doesn''时工作。该类有一个类型为T的动态数组,可以在我的构造函数中实例化。当

类型T为int时,数组的工作方式与我预期的一样。但是当我使用double或

float时,数组指向垃圾和数组元素的任何更新

没有区别。


我在XP专业版机器上使用Visual Studio 2005。以下是

给我带来问题的代码。如果有人可以帮忙解释一下是什么,我错了,为什么这不行,我真的很感激。

提前谢谢。


模板< class T>

class Tuple

{

public:

元组< T>(无效);

元组< T>(T x,T y);

~元组< T>(void);


T getX();

T getY();


void setX(T x);

void setY(T y);

private:

T * _values; // arrray of values

};


模板< class T>

元组< T> ::元组(void )

{

_values = new T [2];

_values [0] = 0;

_values [1] = 0;

}


模板< class T>

元组< T> ::元组(T x,T y)

{

_values = new T [2];

_values [0] = x;

_values [1] = y;

}


模板< class T>

元组< T>: :〜元组(无效)

{

}


模板< class T>

T Tuple< T> :: getX(){return _values [0]; }


模板< class T>

T Tuple< T> :: getY(){return _values [1]; }


模板< class T>

void Tuple< T> :: setX(T x){_ value [0] = x; }


模板< class T>

void Tuple< T> :: setY(T y){_ value [1] = y; }



嗯..我在XP机器上使用VC ++ 2005 Express版本,这个代码

似乎对我来说很好。


ho ******************** @ gmail.com 写道:


我有当我使用< int>,

实现它时,模板类工作正常但是当我使用< floator< doubleit不起作用时。该类有一个类型为T的动态数组,可以在我的构造函数中实例化。当

类型T为int时,数组的工作方式与我预期的一样。但是当我使用double或

float时,数组指向垃圾和数组元素的任何更新

没有区别。


我在XP专业版机器上使用Visual Studio 2005。以下是

给我带来问题的代码。如果有人可以帮忙解释一下是什么,我错了,为什么这不行,我真的很感激。

提前谢谢。


模板< class T>

class Tuple

{

public:

元组< T>(无效);

元组< T>(T x,T y);

~元组< T>(void);


T getX();

T getY();


void setX(T x);

void setY(T y);

private:

T * _values; // arrray of values

};


模板< class T>

元组< T> ::元组(void )

{

_values = new T [2];

_values [0] = 0;

_values [1] = 0;

}


模板< class T>

元组< T> ::元组(T x,T y)

{

_values = new T [2];

_values [0] = x;

_values [1] = y;

}


模板< class T>

元组< T>: :〜元组(无效)

{

}


模板< class T>

T Tuple< T> :: getX(){return _values [0]; }


模板< class T>

T Tuple< T> :: getY(){return _values [1]; }


模板< class T>

void Tuple< T> :: setX(T x){_ value [0] = x; }


模板< class T>

void Tuple< T> :: setY(T y){_ value [1] = y; }



我愿意打赌你的测试代码有不确定的行为。你的
模板类有严重的问题:


a)编译器提供的复制构造函数和赋值运算符将复制

指针而不是元组指出。因此,你的类引用了

语义而不是值语义。


b)构造函数中的内存new [] ed永远不会删除[] d。


这两个陷阱很可能会导致在UB中出现的错误。

因此,所有投注都已关闭。

最佳

Kai-Uwe Bux




Kai-Uwe Bux写道:


我愿意打赌你的测试代码有不确定的行为。你的
模板类有严重的问题:


a)编译器提供的复制构造函数和赋值运算符将复制

指针而不是元组指出。因此,您的类具有引用

语义而不是值语义。



他正在使用一个动态数组...所以如果他使用了复制构造函数,他将b / b $ b $复制对该数组的引用。 ..所以基本上他会重新使用现有阵列的
。这可能是一个无意的错误(或者正是他想要的b $ b,我不知道他的语义),但它不会导致一个数组之间的

差异整数,浮点数和双打数。


但是,使用复制构造函数可能确实提供了未经预料的

行为。如果int和浮点数/双打的测试代码在某种程度上是不同的,并且在测试代码中使用了复制构造函数,那么这可能是

是一个问题区域


>

b)构造函数中的内存new [] ed永远不会删除[] d。



如果删除了元组,你会泄漏内存,这可能会导致UB最终导致UB
,但仍然无法解释

浮点数/双打之间的差异和整个。


I have a template class that works fine when I implement it with <int>,
but when I use <floator <doubleit doesn''t work. The class has a
dynamic array of type T that gets instantiated in my constructor. When
type T is int, the array works like I expect. But when I use double or
float, the array points to garbage and any updates to array elements
make no difference.

I''m using Visual Studio 2005 on an XP pro machine. The following is
the code that is giving me problems. If anyone can help explain what
I''m doing wrong and why this doesn''t work, I''d really appreciate it.
Thanks in advance.
template <class T>
class Tuple
{
public:
Tuple<T>(void);
Tuple<T>(T x, T y);
~Tuple<T>(void);

T getX();
T getY();

void setX(T x);
void setY(T y);
private:
T *_values; //arrray of values
};

template <class T>
Tuple<T>::Tuple(void)
{
_values = new T[2];
_values[0] = 0;
_values[1] = 0;
}

template <class T>
Tuple<T>::Tuple(T x, T y)
{
_values = new T[2];
_values[0] = x;
_values[1] = y;
}

template <class T>
Tuple<T>::~Tuple(void)
{
}

template <class T>
T Tuple<T>::getX() { return _values[0]; }

template <class T>
T Tuple<T>::getY() { return _values[1]; }

template <class T>
void Tuple<T>::setX(T x) { _values[0] = x; }

template <class T>
void Tuple<T>::setY(T y) { _values[1] = y; }

解决方案


ho********************@gmail.com wrote:

I have a template class that works fine when I implement it with <int>,
but when I use <floator <doubleit doesn''t work. The class has a
dynamic array of type T that gets instantiated in my constructor. When
type T is int, the array works like I expect. But when I use double or
float, the array points to garbage and any updates to array elements
make no difference.

I''m using Visual Studio 2005 on an XP pro machine. The following is
the code that is giving me problems. If anyone can help explain what
I''m doing wrong and why this doesn''t work, I''d really appreciate it.
Thanks in advance.
template <class T>
class Tuple
{
public:
Tuple<T>(void);
Tuple<T>(T x, T y);
~Tuple<T>(void);

T getX();
T getY();

void setX(T x);
void setY(T y);
private:
T *_values; //arrray of values
};

template <class T>
Tuple<T>::Tuple(void)
{
_values = new T[2];
_values[0] = 0;
_values[1] = 0;
}

template <class T>
Tuple<T>::Tuple(T x, T y)
{
_values = new T[2];
_values[0] = x;
_values[1] = y;
}

template <class T>
Tuple<T>::~Tuple(void)
{
}

template <class T>
T Tuple<T>::getX() { return _values[0]; }

template <class T>
T Tuple<T>::getY() { return _values[1]; }

template <class T>
void Tuple<T>::setX(T x) { _values[0] = x; }

template <class T>
void Tuple<T>::setY(T y) { _values[1] = y; }

Hmm.. I used VC++ 2005 Express edition on an XP machine and this code
seemed to work fine for me.


ho********************@gmail.com wrote:

I have a template class that works fine when I implement it with <int>,
but when I use <floator <doubleit doesn''t work. The class has a
dynamic array of type T that gets instantiated in my constructor. When
type T is int, the array works like I expect. But when I use double or
float, the array points to garbage and any updates to array elements
make no difference.

I''m using Visual Studio 2005 on an XP pro machine. The following is
the code that is giving me problems. If anyone can help explain what
I''m doing wrong and why this doesn''t work, I''d really appreciate it.
Thanks in advance.
template <class T>
class Tuple
{
public:
Tuple<T>(void);
Tuple<T>(T x, T y);
~Tuple<T>(void);

T getX();
T getY();

void setX(T x);
void setY(T y);
private:
T *_values; //arrray of values
};

template <class T>
Tuple<T>::Tuple(void)
{
_values = new T[2];
_values[0] = 0;
_values[1] = 0;
}

template <class T>
Tuple<T>::Tuple(T x, T y)
{
_values = new T[2];
_values[0] = x;
_values[1] = y;
}

template <class T>
Tuple<T>::~Tuple(void)
{
}

template <class T>
T Tuple<T>::getX() { return _values[0]; }

template <class T>
T Tuple<T>::getY() { return _values[1]; }

template <class T>
void Tuple<T>::setX(T x) { _values[0] = x; }

template <class T>
void Tuple<T>::setY(T y) { _values[1] = y; }

I am willing to bet that your test code has undefined behavior. Your
template class has serious issues:

a) The compiler provided copy constructor and assignment operator will copy
pointers instead of the tuples pointed to. Thus your class has reference
semantics instead of value semantics.

b) The memory new[]ed in the constructor is never delete[]d.

Both pitfalls will very likely cause bugs that manifest themselves in UB.
Thus, all bets are off.
Best

Kai-Uwe Bux



Kai-Uwe Bux wrote:

I am willing to bet that your test code has undefined behavior. Your
template class has serious issues:

a) The compiler provided copy constructor and assignment operator will copy
pointers instead of the tuples pointed to. Thus your class has reference
semantics instead of value semantics.

He is using a dynamic array... so if he used the copy constructor, he
would copy the reference to that array... so basically he would re-use
the existing array. This may be an unintentional bug (or exactly what
he wants, I don''t know his semantics), but it would not cause a
difference between an array of ints, floats and doubles.

However, use of the copy constructor may indeed provide unextpected
behavior. If the testcode for ints and floats/doubles were somehow
different and the copy constructor was used in the testcode, this could
be a problem area

>
b) The memory new[]ed in the constructor is never delete[]d.

You would leak the memory if the Tuple is deleted, which may
eventually result in UB, but still doesn''t explain a difference between
floats/doubles and ints.


这篇关于意外的模板行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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