dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 25

Thread: A non std::vector<> definition

  1. #1
    Join Date
    Jun 2015
    Posts
    157

    A non std::vector<> definition

    Hi,

    Please take a look at exercise 16 here.

    I wrote the code below:

    Code:
    #include <std_lib_facilities_4.h>
    using namespace std;
    
    template <class T> class ovector
    {
    public:
    	ovector() = default;   // default constructor
    	ovector(const ovector& N)  // Copy constructor
    	{
    		for (const auto& v : N.vec)
    			push_back(new T(*v));
    	}
    
    	ovector& operator= (const ovector& N)  // Copy assignment
    	{
    		auto l = N;
    		swap(l.vec, vec);
    		return *this;
    	}
    
    	~ovector() {
    		for (auto ptr : vec)
    			delete ptr;
    	}
    
    	auto begin() const { return vec.begin(); }
    	auto end() const { return vec.end(); }
    	auto size() const { return vec.size(); }
    	void push_back(T* ptr) { vec.push_back(ptr); }
    	void pop_back() { delete vec.back(); vec.pop_back(); }
    	void resize(size_t n) { vec.resize(n); }
    
    	T& operator*(size_t pos) { return *vec[pos]; }
    
    	T& operator[] (size_t pos) { return *vec[pos]; }
    	const T& operator[] (size_t pos) const { return *vec[pos]; }
    
    private:
    	vector<T*> vec; // vector of pointers
    };
    
    //***************************************
    
    int main() {
    
    	ovector<double> v1;
    	for (size_t i = 0; i < 10; i++)
    		v1.push_back(new double(2.5*i));
    
    	cout << "vector<double> v1 = ";
    	for (const auto& v : v1)
    		cout << *v << ' ';
    	cout << endl;
    	*v1(0) = 3;
    	
         system("pause");
         return 0;
    }
    I get these errors on line 54 where I want to use the overloaded operator* there:

    Severity Code Description Project File Line Suppression State
    Error (active) E0980 call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type

    Severity Code Description Project File Line Suppression State
    Error C2064 term does not evaluate to a function taking 1 arguments


    What the problem could be please?

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,001

    Re: A non std::vector<> definition

    Code:
    	T& operator*(size_t pos) { return *vec[pos]; }
    From this definition of operator*, it is used like this

    Code:
    	v1 * 0 = 3;
    why?? - which is probably not what you were expecting/wanting.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.4.5)

  3. #3
    Join Date
    Jun 2015
    Posts
    157

    Re: A non std::vector<> definition

    why?? - which is probably not what you were expecting/wanting.
    I haven't ever seen any use like : v1 * 0 = 3;. It looks very awkward. So I think the exercise wants some other declaration of the operator*.

    And do you think this code is good as an answer to the exercise?

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,001

    Re: A non std::vector<> definition

    You're defined operator* as a binary operator - not as a unary operator that is required when it is used for pointer dereference. For a binary operator you have to provide 2 arguments. When defined as a member function, the first argument is of a class type (eg v1) and the second argument is what is defined for operator*(). In this case a type of size_t. So the syntax to use is eg v1 * 2. What the operator * actually does is decided by the operator() code. It is good practice that what the operator does seems reasonable in the context of someone reading the code - which is why in this case the way it is used does look very awkward. It does work as coded, but is not intuitive as to its meaning when reading code. if I saw v1 * 2 in code and knew that v1 was a vector I would assume that this statement multiplied every element of the vector by 2 - not provide a reference to the second element.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.4.5)

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,001

    Re: A non std::vector<> definition

    Please take a look at exercise 16 here.
    15. Define a pvector to be like a vector of pointers except that it contains pointers to objects and its destructor deletes each object.

    16. Define an ovector that is like pvector except that the [] and * operators return a reference to the object pointed to by an element rather than the pointer.
    How have you implemented the pvector - and the * operator for it? * is not a normal operator (as a pointer deference) for a vector. If the vector held pointers then * would be used to deference a pointer but * would then be an operator for the underlying vector type - not of the vector itself.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.4.5)

  6. #6
    Join Date
    Jun 2015
    Posts
    157

    Re: A non std::vector<> definition

    As far as I understood the case for the operator *, we should firstly have something that that operator is defined (overloaded) for, second, some number as an index to refer to the element (pointer) in the ovector, therefore it sounds that we need a binary operator to characterise these two specification. This is my thought. If you think other way, how would you please defined that operator?

    2. What the operator * actually does is decided by the operator() code.
    Do you mean the default operator()? (If any)

    Apart from above, I also thought of defining an operator() to be used in main() and it itself calls the operator* for getting the value. No success yet.

    If the vector held pointers then * would be used to deference a pointer but * would then be an operator for the underlying vector type - not of the vector itself.
    I couldn't understand this completely, but here is code for exercise 15:
    Code:
    #include <std_lib_facilities_4.h>
    using namespace std;
    
    template <class T> class pvector 
    {
    public:
    	pvector() = default;   // default constructor
    	pvector(const pvector& N)  // Copy constructor
    	{
    		for (const auto& v : N.vec)
    			push_back(new T(*v));
    	}
    	
    	pvector& operator= (const pvector& N)  // Copy assignment
    	{
    		auto l = N;
    		swap(l.vec, vec);
    		return *this;
    	}
    
    	~pvector() { 
    		for (auto ptr : vec) 
    			delete ptr;
    	}
    
    	auto begin() const { return vec.begin(); }
    	auto end() const { return vec.end();  }
    	auto size() const { return vec.size(); }
    	void push_back(T* ptr) { vec.push_back(ptr); }
    	void pop_back() { delete vec.back(); vec.pop_back(); } 
    	void resize(size_t n) { vec.resize(n); }
    	 
    	T*& operator[] (std::size_t pos) { return vec[pos]; }
    	const T*& operator[] (std::size_t pos) const { return vec[pos]; }
    
    private: 
    	vector<T*> vec; // vector of pointers
    };

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,001

    Re: A non std::vector<> definition

    2. What the operator * actually does is decided by the operator() code.
    Do you mean the default operator()? (If any)
    Sorry, my bad. I meant the code for operator*()

    As far as I understood the case for the operator *, we should firstly have something that that operator is defined (overloaded) for, second, some number as an index to refer to the element (pointer) in the ovector, therefore it sounds that we need a binary operator to characterise these two specification. This is my thought. If you think other way, how would you please defined that operator?
    For operator*() on a vector I don't see different - but I wouldn't define operator*() for a vector at all - except as for scalar/vector multiplication. Any other guru got any idea as to what Stroustrup is referring?
    Last edited by 2kaud; September 26th, 2017 at 02:37 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.4.5)

  8. #8
    Join Date
    Jun 2015
    Posts
    157

    Re: A non std::vector<> definition

    Thank you very much.

    For the exercise 17 on the screenshot of the first post, I again can't understand it well enough.
    We can't give arguments to the destructor to tell it what object it deletes. I try to code it myself but would you please explain the exercise what is its meaning?

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,001

    Re: A non std::vector<> definition

    Quote Originally Posted by tomy12 View Post
    Thank you very much.

    For the exercise 17 on the screenshot of the first post, I again can't understand it well enough.
    We can't give arguments to the destructor to tell it what object it deletes. I try to code it myself but would you please explain the exercise what is its meaning?
    17. Define an ownership_vector that holds pointers to objects like pvector, but provides a mechanism for the user to decide which objects are owned by the vector (ie which objects are deleted by the destructor). Hint: This exercise is simple if you were awake for chapter 13.
    So were you awake for Chapter 13? See 13.10 and Appendix E.4 for the hints!
    Last edited by 2kaud; September 27th, 2017 at 04:24 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.4.5)

  10. #10
    Join Date
    Jun 2015
    Posts
    157

    Re: A non std::vector<> definition

    Done! thanks.

    Does the exercise 18 mean that we should define an iterator (class) for the std::vector<>? But the vector itself has its own begin() and end() for range checking!

    And what does "a random access iterator" mean please?
    The problem is only understanding the question the way it is meant. Then I myself will write the code.

  11. #11
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,001

    Re: A non std::vector<> definition

    See http://www.cplusplus.com/reference/iterator/ for info re the various types of iterator.

    I think it means an iterator that can't go out of range. Consider

    Code:
    vector<int> vi {1,1,1,1,1}
    
    for (auto i = vi.begin(); *i || !*i; ++i);
    the iterator i will go out of range as the loop terminator is based upon the value pointed to by the iterator and in this example the termrination condition is always true so i is continually incremented. The 'correct code' is

    Code:
    vector<int> vi {1,1,1,1,1}
    
    for (auto i = vi.begin(); i != vi.end() && *i || !*i; ++i);
    but the exercise seems to want an iterator that is range checked (can't go out of bounds of the container either below or above).
    Last edited by 2kaud; September 29th, 2017 at 05:02 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.4.5)

  12. #12
    Join Date
    Jun 2015
    Posts
    157

    Re: A non std::vector<> definition

    Thank you.

    I've started using this code as a base and will gradually add other features to meet the requirements of a random-access iterator:

    Is this base correct up to now?

    Code:
    #include <std_lib_facilities_4.h>
    using namespace std;
    
    template<class T> class rg_ch_vector {
    
    public:
    	rg_ch_vector() = default;   // Default constructor
    	rg_ch_vector(initializer_list<T> N) {     // Constructor with initializers
    		for (const auto& l : N)
    			vec.push_back(l);
    	}
    
    	rg_ch_vector& operator=(const rg_ch_vector& N) {    // Copy assignment operator
    		vec = N.vec;
    		return *this;
    	}
    
    	rg_ch_vector(const rg_ch_vector& N) {     // Copy constructor (deep copy)
    		vec = N.vec;
    	}
    
    	~rg_ch_vector() {       // Destructor
    		~vec();
    	}
    
    	size_t size() const { return vec.size(); }
    
    	auto begin() const { return vec.begin(); }
    	auto end() const { return vec.end(); }
    
    	void push_back(const T& v) { vec.push_back(v); }
    	void push_front(const T& v) { vec.push_front(v); }
    	void pop_front() { vec.pop_front(); }
    	void pop_back() { vec.pop_back(); }
    
    	T& front() const { return vec.front(); }
    	T& back() const { return vec.back(); }
    
    
    	void operator++() { ++vec; } // forward
    	void operator--() { --vec; } // backward
    
    	T& operator*() { return *vec; } // get value (dereference)
    
    	bool operator==(const rg_ch_vector& b) const { return vec == b.vec; }
    	bool operator!=(const rg_ch_vector& b) const { return vec != b.vec; }
    	ostream& operator<<(const T& b) { return b; }
    
    private:
    	vector<T> vec;
    };
    
    //********************************************
    
    int main()
    {
    	rg_ch_vector<double> vd;
    	vd.push_back(3.5);
    	vd.push_back(8);
    	vd.push_back(7.3);
    	vd.push_back(16);
    
    	cout << *vd << ' ';
    	++vd;
    	cout << *vd << '\n';
    
    	system("pause");
    	return 0;
    }
    I get the error illegal indirection in the line 43 (T& operator*()). why please?

    And I think the destructor doesn't work as needed either. Any idea about the reason?
    And since we haven't any dynamically allocated memory (using new) so there seems to be no need for having a destructor, I suppose.
    Last edited by tomy12; September 30th, 2017 at 12:08 AM.

  13. #13
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,001

    Re: A non std::vector<> definition

    I get the error illegal indirection in the line 43 (T& operator*()). why please?
    vec is of type class vector for which you can't use operator*() to deference. You need to specify an element in the vector to dereference.

    Code:
    void operator++() { ++vec; } // forward
    void operator--() { --vec; } // backward
    This isn't right either for the same reason. The iterator should be incremented/decremented not the vector itself.

    there seems to be no need for having a destructor
    Correct with the code as shown as vector has its own destructor which will get called.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.4.5)

  14. #14
    Join Date
    Jun 2015
    Posts
    157

    Re: A non std::vector<> definition

    1- I thought since the exercise has specified that we are to define an iterator (a random-access iterator), we must have an iterator. So I went for changing the code this way. I'm still not completely sure if it's exactly what the exercise wants or not. But I also think the issue is simpler than what I've thought of. I defined a class named Iterator. If possible please take a look at this whether it's as a whole right for the exercise up to now.

    Code:
    #include <std_lib_facilities_4.h>
    using namespace std;
    
    template<class T> class rg_ch_vector {
    
    public:
    	class Iterator;
    
    	rg_ch_vector<T>() = default;  // Default construtor
    
    	rg_ch_vector<T>(initializer_list<T> N) {     // Constructor with initializers
    		for (const auto& l : N)
    			push_back(l);
    	}
    
    	rg_ch_vector& operator=(const rg_ch_vector& N) {    // Copy assignment operator
    		vec = N.vec;
    		return *this;
    	}
    
    	rg_ch_vector(const rg_ch_vector& N) {     // Copy constructor (deep copy)
    		vec = N.vec;
    	}
    
    	size_t size() const { return vec->size(); }
    
    	Iterator begin() const { return vec.being(); } // iterator to the first element
    	Iterator end() const { return vec.end(); }  // iterator to one beyond the last element
    
    	void push_back(const T& v) { vec.push_back(v); }  // insert v at end
    
    	T& operator[] (std::size_t pos) { return vec[pos]; }
    	const T& operator[] (std::size_t pos) const { return vec[pos]; }
    };
    
    //****************************************
    
    template<class T>
    class rg_ch_vector<T>::Iterator {
    
    private:
    	vector<T>* vec;
    	friend class rg_ch_vector<T>;
    
    public:
    	Iterator(vector<T>* p) : vec(p) {  }
    
    	Iterator& operator++() { Iterator p = vec + 1; return p; } // forward
    	Iterator& operator--() { Iterator p = vec - 1; return p; } // backward
    
    	T& operator*() { return vec*; } // get value (dereference)
    
    	bool operator==(const Iterator& b) const { return vec == b.vec; }
    	bool operator!=(const Iterator& b) const { return vec != b.vec; }
    };
    
    //****************************************************************************
    
    int main()
    {
    	rg_ch_vector<int> v;
    	v.push_back(3);
    	v.push_back(5);
    	cout << v[0] << endl;
    
    	auto p = v.begin();
    	++p;
    	cout << *p << endl;
    
    	system("pause");
    	return 0;
    }

    2- I get the error below for T& operator*() { return vec*; } // get value (dereference).
    error: syntax error: ';'
    I think by an element, you meant I should declare a variable type T to be populated by what the member functions of class rg_ch_vector return, so that its value can be used in Iterator class functions like T& operator*(). Incorrect?
    Last edited by tomy12; October 1st, 2017 at 12:37 AM.

  15. #15
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,001

    Re: A non std::vector<> definition

    But I also think the issue is simpler than what I've thought of. I defined a class named Iterator.
    Yes, Recap section 20.4.2

    Code:
    Iterator begin() const { return vec.being(); } // iterator to the first element
    Iterator end() const { return vec.end(); }  // iterator to one beyond the last element
    Nice, but no. vec.begin() returns type vector::iterator which is not the same as your Iterator class. You need to return your type Iterator.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.4.5)

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)