#i want to know why any value with std::optional is like pointer? like this

95 messages · Page 1 of 1 (latest)

cobalt plume
#
#include <iostream>
#include <optional>

std::optional<int> add(int f, std::optional<int> s = std::nullopt) {
    if (s.has_value() && *s != 0)
        return f + *s;
    else
        std::cout << "no value\n";
        return std::nullopt;
}

int main() {
    std::optional<int> one = add(1);

    if (one.has_value())
        std::cout << *one;
}

why do i have to dereference the std::optional<int> like a pointer? whys it a reference. i want to know it deeper like what the computer is doing or smth idk

prisma siloBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

inland bay
#

you can also do s.value() instead if you prefer

#

the reason you have to do something is because the code needs to differentiate between the optional object and the actual stored object

cobalt plume
cobalt plume
inland bay
#

in c++ we can override most operators in custom classes

cobalt plume
#

and also why cant i print it

inland bay
#

including the dereference operator *

cobalt plume
#

without pointer

inland bay
cobalt plume
cobalt plume
#

sorry for being stupid

inland bay
#

it's basically an abstraction created by the standard library

cobalt plume
#

what

inland bay
#

hmm

cobalt plume
#

still dont understand

inland bay
#

basically, you can't print the address of the optional because it isn't actually a pointer

#

the specific implementation of std::optional is not important to the user, but it is designed purely to either contain a value or not

cobalt plume
#

what kind of address is that

inland bay
#

?

cobalt plume
#

i mean how can the pointer dereference that

inland bay
#

you aren't dereferencing anything

cobalt plume
#

what kind of address is that, since it cant be printed

inland bay
#

you are simply accessing the value held by the optional

cobalt plume
inland bay
#

it just happens to be that the operator is the same

cobalt plume
#

are u sure

inland bay
#

for instance, << is used for logical bit shifts and also for output streams (like cout)

#

/ is used for division and also for concatenating filesystem paths

cobalt plume
#

ok

#

hows that explaining the problem i dont get it

inland bay
#

if it helps understanding you can switch to s.value() instead of *s

inland bay
cobalt plume
#

from the optional

#

idk what u call it

inland bay
#

because there is no address

#

optionals aren't pointers

cobalt plume
#

why can ppl get the value by using * tho

inland bay
viscid terrace
#

Because the * operator is overloaded to return the value

#

That's how they designed it

inland bay
cobalt plume
viscid terrace
#

It's the same as doing myoptional.value()

inner ferry
#

;compile

#include <iostream>
struct S {
    int operator*() { return 5; }
};

int main() {
    S s;
    std::cout << *s;
}
fair wigeonBOT
#
Program Output
5
viscid terrace
cobalt plume
viscid terrace
#

Nothing

inland bay
viscid terrace
#

They do the same

cobalt plume
#

i mean i forgot what it is

viscid terrace
#

You tell what an operator does with a class

cobalt plume
#

give me an example or smth maybe i can remember

inland bay
#

cin/cout

#

cout has an overloaded << operator which allows you to do things like cout << a

cobalt plume
#

is it the operatorfunc+() something

inland bay
#

operator<< yeah

viscid terrace
#

(one of the best features of c++)

cobalt plume
#

i kinda forgot about it a bit

#

how do u implement it again

viscid terrace
#

int MyClass::operator*(){
return 5;
}

#

(very random example)

#

What optional does is

T std::optional::operator*(){
 return this->value();
}
#

Or something similar

cobalt plume
#

oh

#

btw

#
#include <iostream>

// Define the Complex class
class Complex {
private:
    double real;
    double imag;

public:
    // Constructor
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}

    // Overload the + operator
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }

    // Overload the << operator for output
    friend std::ostream& operator<<(std::ostream& os, const Complex& c);
};

// Implement the << operator
std::ostream& operator<<(std::ostream& os, const Complex& c) {
    os << c.real;
    if (c.imag >= 0) {
        os << " + " << c.imag << "i";
    } else {
        os << " - " << -c.imag << "i";
    }
    return os;
}

int main() {
    Complex c1(3.0, 4.0);
    Complex c2(1.0, -2.0);

    Complex c3 = c1 + c2;  // Use overloaded + operator

    std::cout << "c1: " << c1 << std::endl; // Use overloaded << operator
    std::cout << "c2: " << c2 << std::endl; // Use overloaded << operator
    std::cout << "c3: " << c3 << std::endl; // Use overloaded << operator

    return 0;
}```

i found this somewhere, i wonder how does the `std::ostream& operator<<(std::ostream& os, const Complex& c)` dont like check the string in the cout
viscid terrace
#

Check what?

#

The << operator just inserts the data into a stream

cobalt plume
#

i dont get it

#

why did it insert c1 instead of the "c1: "

viscid terrace
#

What

#

They don't

cobalt plume
#

am i questioning they did

#

what

viscid terrace
#

You are looking at the main function brother

#

It's just tests

cobalt plume
#

???

viscid terrace
#

Not the implementation

fair wigeonBOT
#
Program Output
c1: 3 + 4i
c2: 1 - 2i
c3: 4 + 2i
cobalt plume
#

std::ostream& operator<<(std::ostream& os, const Complex& c)

#

this one

viscid terrace
#

Yes and?

cobalt plume
#

why doesnt it pass the "c1: "

#

but instead it specifically pick the c1 (the class object)

viscid terrace
#

What?

cobalt plume
#

ok I understand now I'm happy now