473,385 Members | 1,641 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Assigment operator and container of base type


Below is an example of the problem I am having. I don't understand how
I can get the compiler to see deriv &operator=(const T &rhs).

I am sure this is a common problem - any suggestions?
#include <iostream>
#include <vector>

struct base
{
virtual ~base()=0 {};
};

template<class T>
struct deriv : public base
{
deriv(): data_(0) {};
deriv(const T &data): data_(data) {};
deriv &operator=(const T &rhs) { data_=rhs; return (*this); }
deriv &operator=(const deriv &rhs)
{ data_=rhs.data_; return (*this); }
T data_;
};

struct container
{
base &operator[](int i) { return *(data_[i]); };
std::vector<base *data_;
};

void fill_cont(container &data);

int main(int argc, char *argv[])
{
container data;
fill_cont(data);

std::cout << "data[0]=" << typeid(data[0]).name() << std::endl;
// output: data[0]=struct deriv<int>
data[0]=12445;

std::cout << "data[1]=" << typeid(data[1]).name() << std::endl;
// output: data[1]=struct deriv<double>
data[1]=4.5667;

std::cout << "data[2]=" << typeid(data[2]).name() << std::endl;
// output: data[2]=struct deriv<char *>
data[2]="test";

return 0;
}

void fill_cont(container &data)
{
data.data_.push_back(new deriv<int>());
data.data_.push_back(new deriv<double>());
data.data_.push_back(new deriv<char *>());
}

--

Adrian

Think you know a language? Post to comp.lang... and find out!
Dec 4 '06 #1
10 1750

Adrian napsal:
Below is an example of the problem I am having. I don't understand how
I can get the compiler to see deriv &operator=(const T &rhs).

I am sure this is a common problem - any suggestions?
#include <iostream>
#include <vector>

struct base
{
virtual ~base()=0 {};
};

template<class T>
struct deriv : public base
{
deriv(): data_(0) {};
deriv(const T &data): data_(data) {};
deriv &operator=(const T &rhs) { data_=rhs; return (*this); }
deriv &operator=(const deriv &rhs)
{ data_=rhs.data_; return (*this); }
T data_;
};

struct container
{
base &operator[](int i) { return *(data_[i]); };
std::vector<base *data_;
};

void fill_cont(container &data);

int main(int argc, char *argv[])
{
container data;
fill_cont(data);

std::cout << "data[0]=" << typeid(data[0]).name() << std::endl;
// output: data[0]=struct deriv<int>
data[0]=12445;

std::cout << "data[1]=" << typeid(data[1]).name() << std::endl;
// output: data[1]=struct deriv<double>
data[1]=4.5667;

std::cout << "data[2]=" << typeid(data[2]).name() << std::endl;
// output: data[2]=struct deriv<char *>
data[2]="test";

return 0;
}

void fill_cont(container &data)
{
data.data_.push_back(new deriv<int>());
data.data_.push_back(new deriv<double>());
data.data_.push_back(new deriv<char *>());
}

The code is quite long, but for me is strange for example pure virtual
destructor in base class.

Dec 4 '06 #2

Adrian napsal:
Below is an example of the problem I am having. I don't understand how
I can get the compiler to see deriv &operator=(const T &rhs).

I am sure this is a common problem - any suggestions?
#include <iostream>
#include <vector>

struct base
{
virtual ~base()=0 {};
};

template<class T>
struct deriv : public base
{
deriv(): data_(0) {};
deriv(const T &data): data_(data) {};
deriv &operator=(const T &rhs) { data_=rhs; return (*this); }
deriv &operator=(const deriv &rhs)
{ data_=rhs.data_; return (*this); }
T data_;
};

struct container
{
base &operator[](int i) { return *(data_[i]); };
std::vector<base *data_;
};

void fill_cont(container &data);

int main(int argc, char *argv[])
{
container data;
fill_cont(data);

std::cout << "data[0]=" << typeid(data[0]).name() << std::endl;
// output: data[0]=struct deriv<int>
data[0]=12445;

std::cout << "data[1]=" << typeid(data[1]).name() << std::endl;
// output: data[1]=struct deriv<double>
data[1]=4.5667;

std::cout << "data[2]=" << typeid(data[2]).name() << std::endl;
// output: data[2]=struct deriv<char *>
data[2]="test";

return 0;
}

void fill_cont(container &data)
{
data.data_.push_back(new deriv<int>());
data.data_.push_back(new deriv<double>());
data.data_.push_back(new deriv<char *>());
}

--

Adrian

Think you know a language? Post to comp.lang... and find out!
In container::operator[] you are returning reference to base. But there
is no assignment operator in class 'base', so compiler cannot see it.

Dec 4 '06 #3
Adrian wrote:
>
Below is an example of the problem I am having. I don't understand how
I can get the compiler to see deriv &operator=(const T &rhs).
The problem is that this function doesn't exist in base, which is the static
type. The compiler will only search the object's static type.
>
I am sure this is a common problem - any suggestions?
Surely. You can cast to whatever type you really have:

dynamic_cast<deriv<int>&>(data[0]) = 12445;

Another "solution" follows.
#include <iostream>
#include <vector>

struct base
{
template <class Tbase& operator=(const T&);
virtual ~base()=0 {};
of course this don't work, but your compiler will tell you that.
};

template<class T>
struct deriv : public base
{
deriv(): data_(0) {};
deriv(const T &data): data_(data) {};
deriv &operator=(const T &rhs) { data_=rhs; return (*this); }
deriv &operator=(const deriv &rhs)
{ data_=rhs.data_; return (*this); }
T data_;
};
template <class T>
base& base::operator=(const T& rhs)
{
return dynamic_cast<deriv<T>&>(*this) = rhs;
}
>
struct container
{
base &operator[](int i) { return *(data_[i]); };
std::vector<base *data_;
};

void fill_cont(container &data);

int main(int argc, char *argv[])
{
container data;
fill_cont(data);

std::cout << "data[0]=" << typeid(data[0]).name() << std::endl;
// output: data[0]=struct deriv<int>
data[0]=12445;

std::cout << "data[1]=" << typeid(data[1]).name() << std::endl;
// output: data[1]=struct deriv<double>
data[1]=4.5667;

std::cout << "data[2]=" << typeid(data[2]).name() << std::endl;
// output: data[2]=struct deriv<char *>
data[2]="test";
Of course "test" has type const char[5], not char*, so this will not work.
>
return 0;
}

void fill_cont(container &data)
{
data.data_.push_back(new deriv<int>());
data.data_.push_back(new deriv<double>());
data.data_.push_back(new deriv<char *>());
}
--
Robert Bauck Hamar
Der er to regler for suksess:
1. Fortell aldri alt du vet.
– Roger H. Lincoln
Dec 4 '06 #4
On 2006-12-04 21:07, Adrian wrote:
Below is an example of the problem I am having. I don't understand how
I can get the compiler to see deriv &operator=(const T &rhs).

I am sure this is a common problem - any suggestions?
#include <iostream>
#include <vector>

struct base
{
virtual ~base()=0 {};
};

template<class T>
struct deriv : public base
{
deriv(): data_(0) {};
deriv(const T &data): data_(data) {};
deriv &operator=(const T &rhs) { data_=rhs; return (*this); }
deriv &operator=(const deriv &rhs)
{ data_=rhs.data_; return (*this); }
T data_;
};

struct container
{
base &operator[](int i) { return *(data_[i]); };
std::vector<base *data_;
};

void fill_cont(container &data);

int main(int argc, char *argv[])
{
container data;
fill_cont(data);

std::cout << "data[0]=" << typeid(data[0]).name() << std::endl;
// output: data[0]=struct deriv<int>
data[0]=12445;

std::cout << "data[1]=" << typeid(data[1]).name() << std::endl;
// output: data[1]=struct deriv<double>
data[1]=4.5667;

std::cout << "data[2]=" << typeid(data[2]).name() << std::endl;
// output: data[2]=struct deriv<char *>
data[2]="test";

return 0;
}

void fill_cont(container &data)
{
data.data_.push_back(new deriv<int>());
data.data_.push_back(new deriv<double>());
data.data_.push_back(new deriv<char *>());
}
I'm quite sure you can't do that. Besides from what Ondra Holub has said
what you are trying to do is to create a heterogeneous container, which
I'm quite sure you can't do. At least not like that, you might succeed
if you first find out what kind of deriv it is and cast it to that type.
But then there would not be much of a point, would it?

--
Erik Wikström
Dec 4 '06 #5
Ondra Holub wrote:
In container::operator[] you are returning reference to base. But there
is no assignment operator in class 'base', so compiler cannot see it.
Should be. The compiler should generate one by default.
--

Adrian

Think you know a language? Post to comp.lang... and find out!
Dec 4 '06 #6
Ondra Holub wrote:
The code is quite long, but for me is strange for example pure virtual
destructor in base class.
This is a useful trick for insuring that the class is abstract.

--

Adrian

Think you know a language? Post to comp.lang... and find out!
Dec 4 '06 #7
Robert Bauck Hamar wrote:
Adrian wrote:
The problem is that this function doesn't exist in base, which is
the static
type. The compiler will only search the object's static type.
>I am sure this is a common problem - any suggestions?

Surely. You can cast to whatever type you really have:

dynamic_cast<deriv<int>&>(data[0]) = 12445;

Another "solution" follows.
>#include <iostream>
#include <vector>

struct base
{

template <class Tbase& operator=(const T&);
> virtual ~base()=0 {};

of course this don't work, but your compiler will tell you that.
What wont work. Nothing wrong with a virtual destructor?

template <class T>
base& base::operator=(const T& rhs)
{
return dynamic_cast<deriv<T>&>(*this) = rhs;
}
Perfect. I didnt try that. I assumed the compiler would never be able
to deduce T.

Thanks for that.
>
Of course "test" has type const char[5], not char*, so this will not work.
Was just throwing things into the example :-)

--

Adrian

Think you know a language? Post to comp.lang... and find out!
Dec 4 '06 #8
Adrian wrote:
Robert Bauck Hamar wrote:
>Adrian wrote:
The problem is that this function doesn't exist in base, which is
the static
>type. The compiler will only search the object's static type.
>>I am sure this is a common problem - any suggestions?

Surely. You can cast to whatever type you really have:

dynamic_cast<deriv<int>&>(data[0]) = 12445;

Another "solution" follows.
>>#include <iostream>
#include <vector>

struct base
{

template <class Tbase& operator=(const T&);
>> virtual ~base()=0 {};

of course this don't work, but your compiler will tell you that.
What wont work. Nothing wrong with a virtual destructor?
The dtor _should_, of course, be virtual. But the above line is a syntax
error. You _can_ do:

class foo {
virtual ~foo() = 0;
};

foo::~foo() {}

but not

class foo {
virtual ~foo() = 0 {}
};

--
Robert Bauck Hamar
Der er to regler for suksess:
1. Fortell aldri alt du vet.
- Roger H. Lincoln
Dec 4 '06 #9
Robert Bauck Hamar wrote:
The dtor _should_, of course, be virtual. But the above line is a syntax
error. You _can_ do:

class foo {
virtual ~foo() = 0;
};

foo::~foo() {}

but not

class foo {
virtual ~foo() = 0 {}
};
Gotya. Actually the compiler allows it. I hate it when they dont
follow standards, makes porting a nightmare.

Just found it in the standard. 10.4.2. Makes sense

--

Adrian

Think you know a language? Post to comp.lang... and find out!
Dec 4 '06 #10
Adrian wrote:
Ondra Holub wrote:
>In container::operator[] you are returning reference to base. But there
is no assignment operator in class 'base', so compiler cannot see it.

Should be. The compiler should generate one by default.
Surely. base& base::operator=(const base&) is declared by default. Remarks:

1. It does not match the signature of deriv<T>& deriv<T>::operator=(const
T&)
2. It is not virtual.

1 Means that when the comiler searches base (static type of lhs in
assignment) for operator=, it cannot see any operator= taking a T, even
though the dynamic type of lhs has one.

2 Means that even if the signatures had matched, the compiler would
statically link to base::operator=. Example of latter:

#include <iostream>

using namespace std;

struct foo {
virtual foo& operator =(const foo&) {
cout << "foo\n";
return *this;
}
};

struct bar : foo {
bar& operator=(const foo&) {
cout << "bar\n";
return *this;
}
};

int main() {
foo f;
bar b;

foo & fb = b;

f = f;
b = b;
fb = b;
}

Delete the virtual kw in foo, and see how output changes.

--
Robert Bauck Hamar
Der er to regler for suksess:
1. Fortell aldri alt du vet.
- Roger H. Lincoln
Dec 4 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Dean Mitchell | last post by:
Hi, I have a simple STL map container that maps a stl string to a structure as follows. typedef std::map<std::string,TASKLIST> PCLIST; In a class I have a member variable that is defined as...
4
by: al | last post by:
string s = "original string"; s = "new string"; s.assign("another new string"); Is there any difference using above two way to assign a new string to s? class Derived : public Base {
5
by: Steve | last post by:
Hi, I have a class called cList as so: template<class T> class cList { // base class for Lists private: protected: vector<T> tListOf; // field list container public: void Add(const T& t)...
2
by: yopwojtek | last post by:
Hello All, i know from some tutorials, that copy constructor and assigment operator is not inherited from base to derived class. i think it make sense but i wrote a little example: class Base {...
15
by: Heiner | last post by:
#include <stdio.h> class A { public: virtual A & operator= (const A &); virtual void test(const A &); }; class B : public A
2
by: Mr Dyl | last post by:
I'm having a few issues porting Windows code to Linux (VS.Net 2003 to GCC 4.0.1). So this probably has something to do with VS not catching non-compliant code. I'd like to simplify this problem,...
2
by: allan.mcrae | last post by:
I am having trouble with overloading the += operator when template parameters are used. I have a class holding an array (called "derived" in the following example) which derives from a base class...
13
by: JD | last post by:
Hi, My associate has written a copy constructor for a class. Now I need to add an operator = to the class. Is there a way to do it without change her code (copy constructor) at all? Your help...
19
by: C++Liliput | last post by:
I have a custom String class that contains an embedded char* member. The copy constructor, assignment operator etc. are all correctly defined. I need to create a map of my string (say a class...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.