Show Lecture.ExtensibleNotMutable as a slide show.
2+2
will always be 4
.
int main() { string name = "Jack"; cout << name + 36782; }
c.cc:3: error: no match for 'operator+' in 'name + 36782' (operand types are 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')
That failed, because you can’t use +
on a std::string
and an int
.
string operator+(const string &s, int n) { return s + to_string(n); } int main() { string name = "Jack"; cout << name + 21825; }
Jack21825
Hooray! C++ is extensible! I extended the language to include
string + int
.
class Foo { public: Foo(int value) : n(value) { } int n; }; int main() { Foo f(42); cout << "The foo is " << f << '\n'; }
c.cc:9: error: no match for 'operator<<' in 'std::operator<< <std::char_traits<char> >(std::cout, ((const char*)"The foo is ")) << f' (operand types are 'std::basic_ostream<char>' and 'Foo')
Of course, that failed. <<
has no idea what to do with
an ostream
(output stream) and a Foo
.
class Foo { public: Foo(int value) : n(value) { } int get() const { return n; } private: int n; }; ostream & operator<<(ostream &os, const Foo &f) { os << f.get(); return os; } int main() { Foo f(42); cout << "The foo is " << f << '\n'; }
The foo is 42
Hooray! I extended the language to include ostream + Foo
.
Why the return os
in operator<<
?
class Foo { public: Foo(int value) : n(value) { } int get() const { return n; } private: int n; }; ostream & operator<<(ostream &os, const Foo &f) { return os << f.get(); } int main() { Foo f(42); cout << "The foo is " << f << '\n'; }
The foo is 42
operator<<
can simply return the result of <<
.
Why is operator<<
not a method of Foo
?
class Foo
, it must
take a Foo
as its left-hand argument.
*this
, the current object.
cout << f
, the left-hand argument is an ostream
.
class ostream
.
operator<<
is not a method;
it is, instead, a free function.
Consider this surprising result:
int main() { char now[] = "21:40:57"; cout << now+3 << '\n'; }
40:57
now
is an array of char
.
now
) is the same as a pointer to the first element,
or a char *
.
3
to a pointer moves it forward three items.
I don’t like this. I want it to simply append a "3"
to the string.
Let’s redefine it!
string operator+(char *p, int n) { return p + to_string(n); } int main() { char now[] = "21:40:57"; cout << now+3 << '\n'; }
c.cc:1: error: ‘std::string operator+(char*, int)’ must have an argument of class or enumerated type
That failed. I can’t mutate the language. char * + int
is already
defined, and I can’t change it.
Besides, at least one of the arguments has to be a non-built-in type.
It wouldn’t work if I tried to define operator%(char *p, int n)