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.
210 messages ยท Page 1 of 1 (latest)
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.
@lilac galleon
wait i compilee it
;compile -Wall -Wextra -Wpedantic
#include <cstring>
#include <cstdlib>
#include <cstdio>
enum class Errorstate {
Value,
Error
};
class base_Error {
private:
char* placeholder;
};
template <typename T, typename E>
union Result {
T value;
E err_obj;
};
template <typename T, typename E>
class Expected {
private:
Errorstate errorstate;
Result<T,E> result;
public:
void done() const {
std::printf("DONE");
}
};
template <typename T, typename E>
Expected<T, E> divide(T a, T b) {
Expected<T,E> expected_obj;
return expected_obj;
}
int main() {
Expected<int, base_Error> expected_obj = divide(3,4);
expected_obj.done();
}
<source>: In function 'int main()':
<source>:39:52: error: no matching function for call to 'divide(int, int)'
39 | Expected<int, base_Error> expected_obj = divide(3,4);
| ~~~~~~^~~~~
<source>:33:16: note: candidate: 'template<class T, class E> Expected<T, E> divide(T, T)'
33 | Expected<T, E> divide(T a, T b) {
| ^~~~~~
<source>:33:16: note: template argument deduction/substitution failed:
<source>:39:52: note: couldn't deduce template parameter 'E'
39 | Expected<int, base_Error> expected_obj = divide(3,4);
| ~~~~~~^~~~~
Build failed
@slender fable
Please don't delete forum posts. They can be helpful to refer to later and other members can learn from them. In the future you can use !solved to close a post and mark a post as solved.

could;mt deduce parameter E
why not
i specify it in the return argument and i assign the divide(3,4) to it
how is it supposed to?

You only pass T, how is it supposed to figure out E?
int main() {
Expected<int, base_Error> expected_obj = divide<int, base_Error>(3,4);
expected_obj.done();
}
This would do it for example
like right here
That's not good enough
why not
That has nothing to do with the function call, just where you want to store it

Here, how about this divide(3, 4);
Yeah, what if you typed auto:
int main() {
auto expected_obj = divide<int, base_Error>(3,4);
expected_obj.done();
}
or ```cpp
template<typename E, typename T>
Expected<T, E> divide(T, T) {}
// ...
auto result = divide<base_Error>(3, 4);
Does that work though? I don't think you can specify only some template args
pretty sure it does
The compiler can't decide template args based on what you might do with the return value
hmm
but doing divide<int,base_Error> is not sufficient either

why not
Why not?
+1 bubbles for you
Works on my machine
;compile -Wall -Werror -Wpedantic -Wextra
#include <cstring>
#include <cstdlib>
#include <cstdio>
enum class Errorstate {
Value,
Error
};
class base_Error {
private:
char* placeholder;
};
template <typename T, typename E>
union Result {
T value;
E err_obj;
};
template <typename T, typename E>
class Expected {
private:
Errorstate errorstate;
Result<T,E> result;
public:
void done() const {
std::printf("DONE");
}
};
template <typename T, typename E>
Expected<T, E> divide(T a, T b) {
Expected<T,E> expected_obj;
return expected_obj;
}
int main() {
Expected<int, base_Error> expected_obj = divide<int, base_Error>(3,4);
expected_obj.done();
}
<source>: In instantiation of 'Expected<T, E> divide(T, T) [with T = int; E = base_Error]':
<source>:33:69: required from here
33 | Expected<int, base_Error> expected_obj = divide<int, base_Error>(3,4);
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~
<source>:28:25: error: unused parameter 'a' [-Werror=unused-parameter]
28 | Expected<T, E> divide(T a, T b) {
| ~~^
<source>:28:30: error: unused parameter 'b' [-Werror=unused-parameter]
28 | Expected<T, E> divide(T a, T b) {
| ~~^
<source>: In function 'Expected<T, E> divide(T, T) [with T = int; E = base_Error]':
<source>:30:12: error: 'expected_obj' is used uninitialized [-Werror=uninitialized]
30 | return expected_obj;
| ^~~~~~~~~~~~
<source>:29:19: note: 'expected_obj' declared here
29 | Expected<T,E> expected_obj;
| ^~~~~~~~~~~~
cc1plus: all warnings being treated as er
it doesnt work in godbolt
Apparently it does
link
?
oh camel froth i see
<source>: In instantiation of 'Expected<T, E> divide(T, T) [with T = int; E = base_Error]':
<source>:39:69: required from here
39 | Expected<int, base_Error> expected_obj = divide<int, base_Error>(3,4);
|
like this error i cant understand rally
What happens is:
expected_obj in divide (could've just returned in one line anyway).a and b are unused in divideHere's the fixed version:
yes these are fine
but what about the first
;compile -Wall -Wextra -std=c++20 -Werror
#include <cstring>
#include <cstdlib>
#include <cstdio>
enum class Errorstate {
Value,
Error
};
class base_Error {
private:
char* placeholder;
};
template <typename T, typename E>
union Result {
T value;
E err_obj;
};
template <typename T, typename E>
class Expected {
private:
Errorstate errorstate;
Result<T,E> result;
public:
void done() const {
std::printf("DONE");
}
};
template <typename T, typename E>
Expected<T, E> divide(T, T) {
Expected<T,E> expected_obj{};
return expected_obj;
}
int main() {
Expected<int, base_Error> expected_obj = divide<int, base_Error>(3,4);
expected_obj.done();
}
DONE
This is just explaining what follows
;compile gsnapshot -std=c++23 -Wpedantic -Wall -Wextra
DONE
reading c++ errors is a skill lol
Yeah, that's really just an explanation on where the error is ๐
the "required from here" does not imply to me that "yo silly fix the warnings below
"
yes that is fair
i will pay attention to this in the future
(i f i dont forgort)

idk how wrong my horrible std::expected
but isnt this huge overhead
to just int error propagation like in C?
or whats the benefit of doing the std::expected

(yes i am aware my implementation is probably horrible)
i dont mind people tell me what would be better too ngl
What they mean is that this template instantiation is required because the code requested such a type, but because of the unused parameters and the uninitialized variable it complained in that specific template instantiation.
Basically what you need to look at are these white lines on the left. As long as they continue and don't hit white text it's still in the same function (for the error message I extended the main by a variable e2 that you can also see at the top of the error message), which is why we now have 2 different instantiations, both reporting the same issue.
where is the e2
Why does an expected contain a result? Aren't expected and result supposed to be the same?
There:
int main() {
auto expected_obj = divide<int, int>(3,4);
auto e2 = divide<int, base_Error>(3, 4);
expected_obj.done();
}
The "result" is the expected
union of actual result and error type
The expected class appears to just be a wrapper around that
ye i probably did something very wrong
(In spider man's implemntation i mean)

You can't.
std::variant
std::variant 
But you should get rid of Result.
If you can't see a union, it doesn't exist
It's a poorly named type.
Yeah you should put it within the exppected class too
i dont see why expected is a good name atm
cause that's what you'd expect
๐
but the result is in the expected
You can name it other things.

Isnt this what you guys have in rust...
i dont write rust
... k
Rust calls this type Result.
dot gave me the role when i complained that the rust server did not add the emoji i drew for them in paint

Lol
Haskell calls this type Either.
Sounds like a variant to me
It's a binary variant.
template <typename T, typename E>
Expected<T, E> divide(T a, T b) {
Expected<T,E> expected_obj;
if (b == 0) {
expected_obj.errorstate = Errorstate::Error;
return expected_obj;
}
expected_obj.result.value = a/b;
return expected_obj;
}
int main() {
Expected<int, base_Error> expected_obj = divide<int, base_Error>(3,4);
expected_obj.unwrap();
expected_obj = divide<int, base_Error>(3,0);
expected_obj.unwrap();
return 0;
}
this print
Program stdout
SUCCEEDED
what happened?
TERMINATION
i think this is make sense
โ
No clue bro.
Your old code could only ever print DONE.
Shouldn't the fact that you can default-construct an expected object be concerning?
#include <cstring>
#include <cstdlib>
#include <cstdio>
enum class Errorstate {
Value,
Error
};
class base_Error {
private:
char* placeholder;
public:
void what() const {debug_print("what happened?");}
};
template <typename T, typename E>
union Result {
T value;
E err_obj;
};
template <typename T, typename E>
class Expected {
public:
Errorstate errorstate;
Result<T,E> result;
public:
void terminate() const {
debug_print("TERMINATION");
std::exit(7);
}
void success() const {
debug_print("SUCCEEDED");
}
void unwrap() {
if (errorstate == Errorstate::Error) {
result.err_obj.what();
terminate();
}
else {
success();
}
}
T extracta_value() const {
return result.value;
}
};
template <typename T, typename E>
Expected<T, E> divide(T a, T b) {
Expected<T,E> expected_obj;
if (b == 0) {
expected_obj.errorstate = Errorstate::Error;
return expected_obj;
}
expected_obj.result.value = a/b;
return expected_obj;
}
int main() {
Expected<int, base_Error> expected_obj = divide<int, base_Error>(3,4);
expected_obj.unwrap();
expected_obj = divide<int, base_Error>(3,0);
expected_obj.unwrap();
return 0;
}
```i just add the unwrap instead of the done
idk

No, that should just default construct an error 
std::expected actually has a default ctor.
So I was wrong.
Aw it constructs a non error
So i was wrong too
I think you bit off more than you can chew.
Me or spidey?
Lowkey gives me these vibes: https://github.com/eric19960304/hello-world-overengineering
i already wrote a hello world program
Thanks java
;compile
#include <cstdio>
int main() {
goto Jfbmyzbwsuiyo;Pqydsxkmc:goto Wmviafqorlrwiejqiwdd;Njsyxnuxrh:goto Upfxfhywsjnuz;Jgzshzq:goto Pdrlff;Xqqqfhchtutcap:goto Ncugeiubbeisqlyhhbso;Skiedkrexabfbyxzav:goto Ornqqnv;Hjbjlzdgsfey:goto Rgcjsynbffxdlsnulmmo;Pakmnfkdgcguqhbkgon:goto Nhkecq;Mcgndnegliozlmefoebs:goto Zozcysngirryxusp;Hmspwvkfuyovchrxkg:goto Dwbur;Oolwowcyqzrmfkl:goto Mzarmznkmuj;Ncugeiubbeisqlyhhbso:goto Lukollrgpgh;Xipgzecjiticekknk:goto Njsyxnuxrh;Rpwgxrwzgqibgpvcf:goto Vlxlmflmljhslzdk;Lglottitctvqz:goto Zxlemfjooswuu;Gynwbsleerowwdrbp:goto Ocqjiazala;Oxzgstolvq:goto Jnvdoetdb;Lukollrgpgh:goto Eeewjhbroktzglqj;Eeewjhbroktzglqj:goto Lglottitctvqz;Huzxlaawuvbdtmh:goto Oolwowcyqzrmfkl;Wviljwykdaglnwzgp:goto Lkmiyepzmqmlgtaf;Vlxlmflmljhslzdk:goto Kwunikcicwegjliz;Dwbur:goto Xipgzecjiticekknk;Lkmiyepzmqmlgtaf:goto Gntxkqmb;Kqxdnbdndia:goto Pqydsxkmc;Bkrrbzghqkfrhdw:goto Xqqqfhchtutcap;Khuloudclcdyzru:goto Bxtacr;Jfbmyzbwsuiyo:goto Pakmnfkdgcguqhbkgon;
Fioeqgy:goto Kqxdnbdndia;Glupkyexqbkzly:goto Skiedkrexabfbyxzav;Mzarmznkmuj:goto Ophlnjqvqkh;Xkjjbmcx:goto Jgzshzq;Jnvdoetdb:goto Hjbjlzdgsfey;Wmviafqorlrwiejqiwdd:goto Khuloudclcdyzru;Hrmlj:goto Hmspwvkfuyovchrxkg;Zxlemfjooswuu:goto Hrmlj;Ocqjiazala:goto Xpfblei;Tvzrscowogouubztmo:goto Oxzgstolvq;Upfxfhywsjnuz:goto Huzxlaawuvbdtmh;Buoiymyvem:goto Zevvibusggyuwmwpffj;Xpfblei:goto Buoiymyvem;Nhkecq:goto Ggsyetqimly;Ornqqnv:goto Wviljwykdaglnwzgp;Kwunikcicwegjliz:goto Mcgndnegliozlmefoebs;Bxtacr:goto Glupkyexqbkzly;Zozcysngirryxusp:goto Tvzrscowogouubztmo;Pdrlff:goto Rpwgxrwzgqibgpvcf;Zevvibusggyuwmwpffj:goto Xkjjbmcx;Ggsyetqimly:goto Bkrrbzghqkfrhdw;Rgcjsynbffxdlsnulmmo:printf("Hello Word");goto end;Ophlnjqvqkh:goto Fioeqgy;Gntxkqmb:goto Gynwbsleerowwdrbp;end:return 0;
}
Hello Word
It wouldve been better if you didnt just have printf hello world in there

oh i forgot the std:: u are right
I guess just some Python generated thing, no?
handwritten 
for sure
no ofc python
Cause it's faster to generate with Python
Not really
for you maybe
i am trouble in c/c++
python for me a litle easier
Good practice
I think most people who are equally as skilled in Python as they are in C++ would be a bit faster in Python for this
Yeah but not significantly so
i am use c function alot because i not really started with learncpp. so the std::string and vector stuff is opaque(?) to me
i rather not use it

Your loss

i am still confused about my divide signature
what if instead of my (T a, T b) i have something more complicated
a struct X<type1,type2>
would my divide need more template parameters then for initialization
this would never stop?

?
instead of T being integer because i gave it 3,4
what if i give it instances of
template <typename T1, typename T2>
struct Test {
T1 first_varialbe;
T2 second_varialbe;
};
That will work just fine
without redefine the signature
template <typename T, typename E>
Expected<T, E> divide(T a, T b) {
...
}
ye or give method
and change
expected_obj.result.value = a/b;
// to
expected_obj.result.value = a.div(b);
``` or smth?
i would require the user to only give it types that have div method implemented
that is a worse idea than having / opertaor implemented?
ty help @neat trout @rough barn @lilac galleon @sleek prairie ๐
@slender fable Has your question been resolved? If so, type !solved :)
!solved
You can only close threads you own
Aw
it can only be solved once i do the ;ัin
Tf?
What even is that
So you just searh up ;pin ?
yes with my name
Huh
i only ัin; my questions that are difficult for me, and that i will want maybe revisit