0

I want to make following code work:

Mylist lst;
vector<int> v = lst;

So I see I need to convert my list into a vector. I tried this code:

vector<int> operator=(vector<int> v, const List & l) {
    return v; // more profound stuff later :-)
}

(placed it outside the class). unfortunately Visual Studio throws me: "Error: 'operator=' must be a member function". And I don't get it - what should I do? I can't place this function inside vector class... Can you help me out with that? Thanks!

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Novellizator
  • 13,633
  • 9
  • 43
  • 65
  • 2
    Beyond the interesting case study of how to get this to work (which would be a cast operator) the bigger question is why you don't just say `vector v = lst.getIntVector();` When you get too clever with implicit behaviors you obscure costly operations, invite bugs, and make code harder to understand. There should be a very measurable benefit to using such techniques. – HostileFork says dont trust SE Dec 11 '11 at 15:36
  • To put my comment another way: do you *really* want `Mylist` to be usable and passed as a parameter anywhere one might use a vector of ints with no compiler warning--even though you know that it simply *isn't* a vector of ints...thus modifications of the implicitly produced vector will not be reflected back into the Mylist? Wouldn't it be better to expose an iteration interface through `.begin()` and `.end()` so it could participate in generalized algorithms? If you did that you wouldn't even have to supply an explicit extraction method like `getIntVector`...people could use `std::copy`... – HostileFork says dont trust SE Dec 11 '11 at 15:45
  • [Why do some operators have to be members](http://stackoverflow.com/questions/3938036/rationale-of-enforcing-some-operators-to-be-members) – Armen Tsirunyan Dec 11 '11 at 15:55
  • 1
    What's wrong with `vector v(lst.begin(), lst.end());`? – Kerrek SB Dec 11 '11 at 16:25

5 Answers5

7

You can overload the cast of your type to any other type (see this and other resources easily discoverable by Google). I think this is what you need here. Overloading the assignment operator is used for quite another thing in C++.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
3

You can't overload operator for certain class outside this class. I gues vector is std::vector. What you could do is add to your "Mylist" class method toStdVector() const that would return std::vector.

For example:

class Mylist {
public:
  std::vector<int> toStdVector() const { ... }
};

Mylist list;
std::vector<int> v(list.toStdVector());
Philipp
  • 48,066
  • 12
  • 84
  • 109
Kamil Klimek
  • 12,884
  • 2
  • 43
  • 58
3
Mylist lst;
vector<int> v = lst;

This doesn't call operator= to begin with. It attempt to call a constructor of vector which takes argument of type Mylist. Since no such constructor exists, it gives compilation error.

As for the question in the title, you can definitely overload operator=, but it cannot be a free-function. It has to be a member of a class.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • The C++ states that “An assignment operator shall be implemented by a non-static member function” (§13.5.3/1), and GCC requires that as well. – Philipp Dec 11 '11 at 15:41
  • @Philipp: Did I say anything else? – Nawaz Dec 11 '11 at 15:55
  • 1
    Basically this means you can't have an assignment operator where the left hand value is not your class. – UncleBens Dec 11 '11 at 18:13
  • @UncleBens: That is misleading. I can define my own class `A`. Now can I define `=` as free function such as `A a,b; a =b;`? Surely, the left hand side is my own defined class. – Nawaz Dec 11 '11 at 18:18
2

To make MyList lst; std::vector v = lst;

To make the above work you'll need to overload operator std::vector<int> () (or any other variable type that is compatible with std::vector<int>) in MyList, see the following example.

Another way of doing it is to provide a method that you explicitly call to return a std::vector<int> "version" of your object. std::vector<int> v = obj.to_int_vector (), it's pretty much the same implementation as in the below example.

Example

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

struct Obj {
  operator std::vector<int> () const {
    return std::vector<int> (data, data+3);
  }   

  int data[3];
};  

int 
main (int argc, char *argv[])
{   
  Obj o;

  o.data[0] = -1; 
  o.data[1] =  2;  
  o.data[2] = 99; 

  std::vector<int> v = o;

  std::copy (v.begin (), v.end (), std::ostream_iterator<int> (std::cout, " "));
} 

output:

-1 2 99
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
1

You may provide operator vector<int> So if you put vector<int> v = lst;, the operator vector` would be called and operator= for vector will be allowed.

class MyList {
public:

operator vector<int> () const
{
    return some_valid_vector;
}
};
Yappie
  • 399
  • 2
  • 8