overloading a simple = operator - c++

I am trying to overload part of my class to a string and I can't get the overloading to work. Alternatively, I will also have a long long overload, but I just assume that it will be the same excepted for long long instead of string.
class FileData
{
public:
string extensions_;
unsigned long long containsBytes_;
};
string& operator = (string& s , FileData& fd)
{
s= fd.extensions_;
return s;
}
string extName = fileVector[0];
The error I keep getting is ERROR:'operator=' must be a member function.
I also tried using istream but that also didn't work.
Anybody know how I could go about this?

To be able to assign to a string from your class, you'll need a conversion operator:
class FileData
{
public:
// Conversion to string
operator string() const {return extensions_;}
string extensions_;
unsigned long long containsBytes_;
};
You can only overload the assignment operator as a member of your class, for the purpose of assigning to an object of that class.

You can't overload the operator= of std::string. What you probably want is a cast operator:
class FileData
{
public:
string extensions_;
unsigned long long containsBytes_;
operator string()
{
return extensions_;
}
}

Related

How do I initialize a string with an object?

So I was wondering if I could do something like the following in C++.
#include <string>
using namespace std;
class foo
{
public:
string bar;
string baz;
foo(const string &faz)
:bar(faz)
{
};
};
int main()
{
const foo foo1("somestring");
bool isTrue = ((std::string(foo1) == "some string");//This should be true
return 0;
}
How would I make std::string(foo1) equal "some string"? Is there some special variable name I need to use? Or is there something else I need to be doing? Please tell me if you know
You've basically got 2 options:
add a conversion operator, so that a foo can implicitly convert to string
define operator== for foo.
The first option may seem attractive at first, but code that uses conversion operators can quickly get out of hand - overload resolution is tricky enough as it is without adding more possible pathways.
The operator== version is quite simple (note, by making it a non-member you allow the char array to appear on the left of the ==):
bool operator==( foo const &f1, foo const &f2 )
{
return f1.bar == f2.bar;
}
You would use it like:
bool isTrue = (foo1 == "some string");
This matches char arrays because foo has a converting constructor, and the implicit conversion chain of char[] -> char * -> const std::string & happens.

Integer c++ wrapper

I'm doing a very small and simple Integer class wrapper in C++, which globaly looks like this:
class Int
{
...
private:
int value;
...
}
I handled almost all the possible assignements, but I don't find out what kind of operator I have to use to get native left assignement.
eg:
Int myInteger(45);
int x = myInteger;
You might want a conversion operator to convert to int:
class Int
{
public:
operator int() const { return value; }
...
};
This allows the following initialization of an int
int x = myInteger;
In C++11, you can decide whether you restrict that conversion to int, or whether you allow further conversions from int to something else. To restrict to int, use an explicit conversion operator:
explicit operator int() const { return value; }
although it is probably not necessary in this case.

Overwrite Cast Operator in C++

As a C++ beginner I want to write some simple type casts. It there a way to create casting logic which can be used in the type new = (type)old format with the prefix parentheses?
string Text = "Hello";
char* Chars = "Goodbye";
int Integer = 42;
string Message = Text + (string)Integer + (string)Chars + "!";
I'd like to stick with this syntax if possible. For example the string cast of boost int Number = boost::lexical_cast<int>("Hello World") has an unattractive long syntax.
Just use a normal function that you overload for different types:
std::string str(int i) {
return "an integer";
}
std::string str(char* s) {
return std::string(s);
}
Then use if not like a cast, but as a normal function call:
string Message = Text + str(Integer) + str(Chars) + "!";
It's the most common thing in C++ to cast using a NAME<TYPE>(ARGUMENT) syntax, like in static_cast<int>(char). It makes sense to extend this the way boost does.
However, if you want to convert non-primitive types, you can use non-explicit constructors with a single argument and the cast operator.
class MyType {
public:
MyType(int); // cast from int
operator int() const; // cast to int
};
This is not possible if you are dealing with already existing types.
You cannot change the behaviour of the C-style cast. C++ will make up its mind how to interpret such a cast.
You could however come up with an intermediate type that shortens the syntax:
template <typename From>
struct Cast {
From from;
Cast(From const& from) : from(from) {}
template <typename To>
operator To() const {
return convert(from,To());
}
};
template <typename From>
Cast<From> cast(From const& from) {
return Cast<From>(from);
};
std::string convert(int, std::string const&);
This would allow you to convert things explicitly but without stating how exactly:
int i = 7;
std::string s = cast(i);

Using a wrapped integer as index in C++?

Assuming I have a (trivial) class that wraps normal int type in C++ for random integers, how can I use an instance of this class like an integer when indexing an array or picking a character from a string?
If it's a matter of operator overloading, then which operator?
As a specific example, I have a Random class and I pick characters at random locations in a string like this:
string chars = "whatever";
Random R = Random(0, chars.length());
other_chars += chars.at(R.getValue());
But instead, I'd rather have other_chars += chars.at(R); But how?
You need a user defined conversion operator.
class Random
{
int x_;
public:
operator int() const { return x_; }
};
Have you tried overloading operator int() inside the wrapper Random. I believe it should be something like,
class Random
{
int value;
public:
// ... constructors and operator =
operator int () const { return value; }
};
You need typecast operator overloading: operator int() { return _value; }.
Here is more explanation.

C++ STL question related to insert iterators and overloaded operators

#include <list>
#include <set>
#include <iterator>
#include <algorithm>
using namespace std;
class MyContainer {
public:
string value;
MyContainer& operator=(const string& s) {
this->value = s;
return *this;
}
};
int main()
{
list<string> strings;
strings.push_back("0");
strings.push_back("1");
strings.push_back("2");
set<MyContainer> containers;
copy(strings.begin(), strings.end(), inserter(containers, containers.end()));
}
The preceeding code does not compile. In standard C++ fashion the error output is verbose and difficult to understand. The key part seems to be this...
/usr/include/c++/4.4/bits/stl_algobase.h:313: error: no match for ‘operator=’ in ‘__result.std::insert_iterator::operator* [with _Container = std::set, std::allocator >]() = __first.std::_List_iterator::operator* [with _Tp = std::basic_string, std::allocator >]()’
...which I interpet to mean that the assignment operator needed is not defined. I took a look at the source code for insert_iterator and noted that it has overloaded the assignment operator. The copy algorithm must uses the insert iterators overloaded assignment operator to do its work(?).
I guess that because my input iterator is on a container of strings and my output iterator is on a container of MyContainers that the overloaded insert_iterator assignment operator can no longer work.
This is my best guess, but I am probably wrong.
So, why exactly does this not work and how can I accomplish what I am trying to do?
What would work would be using the constructor (which would make more sense instead of the assignment):
class MyContainer {
public:
string value;
MyContainer(const string& s): value(s) {
}
};
Then the second problem is that set also requires its contents to be comparable.
As to the cause, insert_iterator works by overloading operator=:
insert_iterator<Container>& operator= (typename Container::const_reference value);
As you can see, the righthand value must be either the value type of the container or implicitly convertible to it, which is exactly what a (non-explicit) constructor achieves and the assignment operator doesn't.
Technically you could also make it work without changing the class (e.g if you don't want an non-explicit constructor) by providing a suitable conversion function:
MyContainer from_string(const std::string& s)
{
MyContainer m;
m = s; //or any other method how to turn a string into MyContainer
return m;
}
which can be used with std::transform:
transform(strings.begin(), strings.end(), inserter(containers, containers.end()), from_string);
You need to add:
1. Constructor that takes string (you are trying to add string to container that can contain MyContainer objects).
2. bool operator < (set uses it by default to compare elements)
For instance :
class MyContainer
{
public:
MyContainer(const string& v):value(v){};
};
bool operator <(const MyContainer &c1, const MyContainer &c2)
{
return c1.value <c2.value;
}
The problem is twofold:
You're trying to fill a set of MyContainer objects
... from a list of string objects.
The copy() algorithm tries to convert each string object to a MyContainer object. In C++ to add to class MyContainer conversion support from type string to type MyContainer you need to add a constructor that takes a parameter of type string:
struct MyContainer {
MyContainer(const string& s) : value(s) { }
bool operator<(const MyContainer& o) const { return value < o.value; }
private:
string s;
};
You don't need an assignment operator, because the compiler can get the copying done by the copy-constructor: convert a string to a MyContainer and then use the default assignment operator to assign one MyContainer object onto the other. You will, however need an operator<() because C++ sets are sorted.