#include <vector>
#include "A.h"
int main(void)
{
std::vector< NS::A<float> > vec;
NS::A<float> a;
vec.push_back(a);
return 0;
}
🔒 Locked
Operator overloading operator& and std.
Advertisement
Original Post
I have a template called A that has constructor, destructor and a function that overloads operator&. When I try to put objects of type A into a std::vector it fails. Here's an example. It works just fine in VC++ 6.0 sp 6 but it doesn't work in GCC 3.2. Deos std use my overloaded opertator& when it tries to get the address of the object?
Ok, here's an complete example. Should have posted it from the beginning...
class A
main func
Error message from GCC (the last lines are the most import I guess):
C:/program/programmering/Dev-Cpp/include/c++/bits/stl_construct.h: In function
*, std::vector, std::allocator > > >, _ForwardIter = __gnu_cxx::__normal_iterator*, std::vector, std::allocator > > >]'
C:/program/programmering/Dev-Cpp/include/c++/bits/stl_uninitialized.h:112: instantiated from, _Alloc = std::allocator >]'
C:/program/programmering/Dev-Cpp/include/c++/bits/stl_vector.h:496: instantiated from' to `int' in initialization
where main line 8 is vec.push_back(a);
class A
namespace B { template <typename T> class A { private: T x[3]; public: A(T y) {}; virtual ~A() {}; inline T* operator&() { return x; } };}main func
#include <vector>#include "A.h"int main(void){ B::A<int> a([2]); std::vector< B::A<int> > vec; vec.push_back(a); return [0];}Error message from GCC (the last lines are the most import I guess):
C:/program/programmering/Dev-Cpp/include/c++/bits/stl_construct.h: In function
void std::_Construct(_T1*, const _T2&) [with _T1 = int, _T2 = B::A]':
C:/program/programmering/Dev-Cpp/include/c++/bits/stl_uninitialized.h:87: instantiated from _ForwardIter std::__uninitialized_copy_aux(_InputIter, _InputIter, _ForwardIter, __false_type) [with _InputIter = __gnu_cxx::__normal_iteratorC:/program/programmering/Dev-Cpp/include/c++/bits/stl_uninitialized.h:112: instantiated from
_ForwardIter std::uninitialized_copy(_InputIter, _InputIter, _ForwardIter) [with _InputIter = __gnu_cxx::__normal_iterator*, std::vector, std::allocator > > >, _ForwardIter = __gnu_cxx::__normal_iterator*, std::vector, std::allocator > > >]'
C:/program/programmering/Dev-Cpp/include/c++/bits/stl_vector.h:901: instantiated from void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<_Tp*, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = B::AC:/program/programmering/Dev-Cpp/include/c++/bits/stl_vector.h:496: instantiated from
void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = B::A, _Alloc = std::allocator >]'
main.cpp:8: instantiated from here
C:/program/programmering/Dev-Cpp/include/c++/bits/stl_construct.h:78: cannot
convert const B::Awhere main line 8 is vec.push_back(a);
Overloading the address of operator on a class makes it ineligible for use in a standard library container (unless you define it to do the exact same thing as the built in address of operator). Specifically, it violates the requirements set down in section 20.1.3 of the C++ standard.
Jingo and you other guys are probably right. But it works fine in VC++ 6 and I got the idea of solving a problem this way from the 3ds-max SDK where they have a vector class that looks something like this.
class Vector {private: float x,y,z;public: Vector() {} ~Vector() {} const float* operator&() { return &x }}
Sure the pointers are the same, at least for basic types. Otherwise it wouldn't be possible wo have an array of vertex-objects without losing alot of speed.
If you have an array of vertex objects and iterate through them. You will loose more than 25 percent of execution time if you add extra data between the objects. If you have an object with float x,y,z then the array will become x,y,z,x,y,z,x,y,z and so on. The adress of x will always be the same as the address of the object. If you have a vertex class, just add a float w and see how the speed decreases alot. At least on Athlon XP+ CPUs.
If you have an array of vertex objects and iterate through them. You will loose more than 25 percent of execution time if you add extra data between the objects. If you have an object with float x,y,z then the array will become x,y,z,x,y,z,x,y,z and so on. The adress of x will always be the same as the address of the object. If you have a vertex class, just add a float w and see how the speed decreases alot. At least on Athlon XP+ CPUs.
Quote:
Original post by __fold
Jingo and you other guys are probably right. But it works fine in VC++ 6 and I got the idea of solving a problem this way from the 3ds-max SDK where they have a vector class that looks something like this.
*** Source Snippet Removed ***
If your doing this so you can pass a vector to a some function that requires an array or a pointer to an array (as in opengl functions) as it's argumenets e.g.
Vector3f v;glVertex3fv(v);Then you overload the cast operators for that e.g.
Vector3
#include <cstddef>template< typename T >class Vector3 {public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T value_type; typedef T* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef Vector3<T> _self;private: value_type _n[3];public: operator const T*() const { return _n; } operator T*() { return _n; } //default constructor Vector3(T x = 0, T y = 0, T z = 0); Vector3(T n[]); //copy constructor Vector3(const _self& _v); //assigment _self& operator=(const _self& _v); const_reference operator[](difference_type i) const { return _n; } reference operator[](difference_type i) { return _n; } // add more methods};EDIT: Provide constant & non-constant version of the function
[Edited by - snk_kid on July 4, 2004 6:40:58 AM]
snk_kid: Hmm, that is what I want to do when I think about it. I really have to check why I have overloaded operator& from the bginning. Now atleast I know why it doesn't work and I agree that it shouldn't work. It's a cast I probably thought of when I designed the class.
Thanks for all the replies!
Thanks for all the replies!
Quote:
Original post by Jingo
You shouldn't really use names beginning with an underscore snk_kid, they are reserved by the standard to the implementation for use in the global namespace. For all you know _n could be a macro for int.
Well, he's not at global scope, he's in a class scope. That makes names beginning with a single underscore and a lowercase letter perfectly legitimate. Considering that macros do not respect scope, _n could not be a macro for int.
It is names starting with two underscores or an underscore and an uppercase letter which are reserved at any scope, for any usage. So __n or _N could be a macro, or a special compiler keyword (__declspec anyone?)
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement