I'm trying to take input from the user and the user have multiple choice to enter the different types of inputs(char, int float). And according to the value entered I have to take proper action.
eg. I have a function below :-
int* function(int data)
{
int a[50];
int k = 0;
a[k] = data;
k++;
// I want to make choice generalized so that it can accept both type of
// values int as well as char.
cout<<"\n Enter integer element to insert into array, otherwise press 'n' to terminate array list: ";
cin>>choice;
if(choice != 'n')
function(choice);
return a;
}
So, in the above example I want to make choice generalized. I how to use template for function and classes but, I want to do this for variable. Please help.
NOTE: the above code is just a example to illustrate my problem.
Thank's.
Templates are a compile time construct, so there is no way to let the user input have an influence on the template type.
What you can do is some template based automation of the input conversion where you decide which template instantiations should be checked. Suppose you have a class to handle your input conversion called GenericInput with template functions bool GenericInput::CanConvert<TargetType>() and TargetType GenericInput::Convert<TargetType>()
GenericInput in;
std::cin >> in;
if (in.CanConvert<int>()) {
// some action
}
else if (in.CanConvert<char>()) {
// another action
}
// ...
It would basically be a wrapper for the idea to first read the string and then check, how the string can be interpreted.
To implement it, you would need the following things:
Overload operator >>
std::istream& operator >>(std::istream& stream, GenericInput& element) {
/* TODO: read input into string member of GenericInput object */
return stream;
}
The GenericInput class
class GenericInput {
private:
std::string _inputElement; // store input as base for conversion
public:
// TODO: standard class implementation
template <typename TargetType>
bool CanConvert() {
// TODO: create std::stringstream from _inputElement and try to read into a TargetType variable
// return true if the stringstream is valid after the read
}
template <typename TargetType>
TargetType Convert() {
// TODO: create std::stringstream from _inputElement and try to read into a TargetType variable
// return variable if the stringstream is valid after the read, otherwise report error
}
}
Regarding the "valid" stringstream after read, it might be important to check two things: if the stringstream is in some kind of error state, conversion failed. If there are unread characters in the stringstream, the conversion was incomplete, which may also count as a failure.
Please don't expect this to be working out of the box, its more of an idea scratch than an actual implementation.
Related
#include <iostream>
#include <map>
using namespace std;
string read(string a){return "abc";}
void read(float a){}
bool read(int a){return true;}
int main()
{
map<string,string(*)(string)> f1;
map<string,void(*)(float)> f2;
map<string,bool(*)(int)> f3;
f1["read"]=read;
f2["read"]=read;
f3["read"]=read;
string t,u;
while(1)
{
cin>>t>>u;
if(!f1.count(t)||!f2.count(t)||!f3.count(t)) cout<<"Unknown command!\n";
else cout<<f1[t](u);
}
}
Here I want to access these overloaded functions through their keys. But how can I (or can I ever) store them all in one single map? Something like map<string,/*---*/> f; that is capable of mapping different functions that have different parameter types and different return types so that I can use f["read"]=read; at once?
You cannot have a set of overloads as one element in a map. You could put some objects in the map that have overloaded member functions, though that also wont help, as you want elements in the map with different overloads.
Next problem is that when the parameters are from user input, you need to decide what overload you want to call before you call it. Usually you let the compiler decide based on paramters, but here you need to parse user input to the type of the parameters.
Further, elements in the map must all be of same type. That type should provide an interface that allows you to call the functions in a convenient way.
In other words, the easy way is to wrap functions into something that always takes the same paramter and always returns the same and then put that something into the map. I suggest to use std::istream for input and std::ostream for output :
#include <iostream>
#include <map>
#include <functional>
std::string read(std::string a){return "abc";}
void read(float a){}
bool read(int a){return true;}
int main()
{
std::map<std::string,std::function< void(std::istream&,std::ostream&)>> f;
f["read"] = [](std::istream& in,std::ostream& out){
std::string input;
in >> input;
// put logic to decide what overload to call here
bool call_string = true;
bool call_int = false;
bool call_bool = false;
if (call_string) {
out << read("foo");
} else if (call_int) {
out << read(42);
} else if (call_bool) {
//note : read(bool) returns void
read(false);
};
// use the map:
std::string t;
std::cin >> t;
f[t](std::cin,std::cout);
}
For input "read 42" the output is
abc
Live Example
PS: I you wouldn't insist on overloads the parsing could be automated to some extend by deducing the argument and return types of the functions to be put in the map, though it wont work with overloads (and would be a different question).
I handled the case according to #idclev 463035818's first suggestions, thanks to them.
Here's my recent sample;
#include <iostream>
#include <fstream>
#include <map>
using namespace std;
typedef string (*func)(string);
struct demo
{
map<string,func> f;
}g;
string read_p(string),read(string),read(int);
int main()
{
g.f["read"]=read_p;
while(1)
{
cout<<">>";
string t;
getline(cin,t);
size_t found=t.find(" ");
if(found==-1){if(!g.f.count(t)) cout<<"Unrecognized command!\n"; else cout<<g.f[t](t);}
else
{
string a=t.substr(0,found),b=t.substr(found+1,t.length()-found);
if(!g.f.count(a)) cout<<"Unrecognized long command!\n"; else cout<<g.f[a](b);
}
}
return 0;
}
string read_p(string c)
{
if(c=="read") return "Read what?\n";
else if(c=="story") return read(c);
else if(c.substr(0,4)!="page") return "Can't read that!\n";
else
{
size_t found=c.find_first_of("0123456789");
if(found==-1) return "Choose a page!\n";
else
{
int d=atoi((c.substr(found,2)).c_str());
return read(d);
}
}
}
string read(string a)
{
ifstream counter("game.txt",ifstream::in);
string x3;
int line=0;
while(counter.good()){getline(counter,x3); line++;}
counter.close();
string x1[line],x2="\"";
ifstream x("game.txt",ifstream::in);
for(int i=0; i<line; i++)
{
getline(x,x1[i]);
x1[i].erase(0,3);
x2.append(x1[i]+"\n");
}
x.close();
x2.erase(x2.length()-2,2);
x2.append("\"\n");
return x2;
}
string read(int a)
{
if(a<14||a>18) return "Choose another page!\n";
int page=-1;
ifstream x("game.txt",ifstream::in);
string x1;
while(a!=page){getline(x,x1); page=atoi((x1.substr(0,2)).c_str());}
x1.erase(0,3);
x1.insert(0,"\"");
x1.append("\"\n");
return x1;
}
I put the map into a struct so it's also accessible from local functions. Then when anything begins with "read" is entered, program calls read_p function with the user-input string as parameter. read_p parses that in my easy way and decides which variation of read to call. read is overloaded to be able to handle strings and integers separately. When a string is passed as parameter, read(string a) is called; and when an int is passed, read(int a) is called.
This method works precisely. Mapping the functions that are in the same format and that will parse input, then overloading different functions related to them. If any other user-input commands to be added, we'll just add g.f["command"]=command_p; that will parse it and overloaded variations of the function command. I'm sure there must be better ways, if anyone wants to help, I'll be glad about it.
Something similar to what you suggested is used by Qt framework for event handling. Said framework casts all slot function pointers to void* and is cast back before use. The code generation for that is done by meta-object compiler.
I suspect its a implementation-defined behavior that actually is viable on most of platforms as longs as you properly track which pointer points at which function. Lately their design became more complex to support lambda expressions for handlers.
I was trying to make a program, which automatically detects the data type of input given by user.
My approach :
int input(istream& i)
{
int k;
i>>k;
return k;
}
float input(istream& i)
{
float k;
i>>k;
return k;
}
void showval(int h){cout<<h;}
void showval(float h){cout<<h;}
int main()
{
showval(input(cin));
return 0;
}
As you can see, I used overloading of parameters and overloading of return type of two different functions, but at the same time. However, the program gives error as
"new declaration float input(istream& i) disambiguates the old
declaration int input(istream& i)”.
I don’t understand, how this creates ambiguity. Is it because, the two different functions (showval and input) are dependent?
Also after going through few articles on overloading, what i realised is that in C++, methods can be overloaded only if they differ by parameters.
However this link has a trick by which he was able to overload functions by return type. Is it possible to use the same trick in my program? Also, is there any way by which i can tell the compiler that the function input has parameter which is user dependent, and its data type may or may not differ. Does C++ forbid such possibilty?
Let's say that types such as int and float are specific, and types such as the proxy object shown in the linked question are generic. Our options are to be specific to begin with, in which case we just coast through the rest, or we give rise to a generic type and handle all the various specific types we may support.
The proxy object shown in the linked question is an example of a variant type, and boost::variant is a generic implementation of this. For example, boost::variant<int, float> allows us to hold either int or float.
My recommendation really depends what you want. Do you
want to specify the type you expect to get from the user and throw on unexpectd input? (specific to begin with and coast) OR,
want to give rise to a different type depending on what the user inputted and specify a set of types you can handle? (Give rise to a generic type and handle the various specific types)
Specifying the type you expect from the user
In this case we can simply make the function templated and we specify the type we expect through the template parameter.
The example shown is kept totally generic but you can restrain template parameters using various techniques. Check out my answer regarding this topic.
#include <iostream>
/* Read data of type T from an input stream. */
template <typename T>
T read(std::istream &strm) {
T val;
strm >> val;
if (!strm) {
throw /* something */;
} // if
return val;
}
/* Print data of type T. */
template <typename T>
void print(const T &val) {
std::cout << val;
}
int main() {
print(read<int>(std::cin));
}
This will give rise to an int for input such as 1 and even for input such as 1., 1.0 and 1.2.
Handling different types you may get from the user
In this case we're actually lexing the input stream from the user. Our read function will give rise to a generic type, boost::variant<int, float>.
#include <iostream>
#include <boost/variant.hpp>
/* Naive implementation of a lexer. */
boost::variant<int, float> read(std::istream &strm) {
std::string lexeme;
strm >> lexeme;
try {
std::size_t idx;
auto val = std::stoi(lexeme, &idx);
if (idx == lexeme.size()) { // Make sure we converted the entire lexeme.
return val;
} // if
} catch (const std::exception &) {
// Do nothing. We'll try to lex it as float instead.
} // try
std::size_t idx;
auto val = std::stof(lexeme, &idx);
if (idx == lexeme.size()) { // Make sure we converted the entire lexeme.
return val;
} // if
throw /* something */;
}
/* Print the type and the value, to check that we have the correct type. */
void print(const boost::variant<int, float> &val) {
class visitor : public boost::static_visitor<void> {
public:
void operator()(int that) const {
std::cout << "int: " << that << std::endl;
}
void operator()(float that) const {
std::cout << "float: " << that << std::endl;
}
}; // visitor
boost::apply_visitor(visitor(), val);
}
int main() {
print(read(std::cin));
}
This approach will give rise to int for input such as 1, and give rise to float for input such as 1., 1.0 as 1.2.
As you can see, we give rise to a generic type, boost::variant<int, float>, and handle the various specific types, int and float, in the visitor.
The problem is that the compiler cannot possibly know which version of input to call. It is only within input that you actually attempt to extract from the stream, and only at that point can you know what the user has inputted. And even then, there's no reason the user can't enter 1.5 and then you extract into an int, or they enter 5 and you extract into a float.
Types are compile-time constructs. The compiler uses the type information to produce the program executable, so it must know what types are being used at compile time (way before the user inputs anything).
So no, you can't do this quite like this. You could extract a line from the input, parse it to determine whether it's a floating point value or an integer (does it have a .?), and then have a separate execution path for each case. However, instead I recommend deciding what the input that you expect from the user is (an int or a float?) and just extract that.
And also no, the trick with the proxy won't work for you. Firstly, as I mentioned, the format of the input is not known at compile time anyway. But secondly, in that code, the type that was required was known by the type of the variable being declared. In one line they did int v = ... and in the other they did double u = .... In your case, you're passing the result to showval which could take either an int or double and the compiler has no idea which.
I am aware of the process of function overloading in C++ through the use of differing parameters and definitions. However if I have two functions which are identical apart from their parameters is there a way to only have this definition once.
The functions I have used are to check for correct input (i.e. a number not a character is entered). One is for an int and the other a float. Because of this and the fact that I pass the variable by reference the definitions are exactly identical.
The two functions declarations are as follows:
void Input (float &Ref);
void Input (int &Ref);
And they then share the common definition of:
Function_Header
{
static int FirstRun = 0; // declare first run as 0 (false)
if (FirstRun++) // increment first run after checking for true, this causes this to be missed on first run only.
{ //After first run it is required to clear any previous inputs leftover (i.e. if user entered "10V"
// previously then the "V" would need to be cleared.
std::cin.clear(); // clear the error flags
std::cin.ignore(INT_MAX, '\n'); // discard the row
}
while (!(std::cin >> Ref)) // collect input and check it is a valid input (i.e. a number)
{ // if incorrect entry clear the input and request re-entry, loop untill correct user entry.
std::cin.clear(); // clear the error flags
std::cin.ignore(INT_MAX, '\n'); // discard the row
std::cout << "Invalid input! Try again:\t\t\t\t\t";
}
}
If there was a way around having to have two identical copies of the same code while it still being used for both parameter types then I could shorten the code of my programme significantly. I'm sure I'm not the only person with this issue but all my searches are returning are explanations of how to overload functions using multiple definitions.
Any help or advice would be much appreciated.
The best (and only ?) solution is to use template
Templates are useful:
template <typename T>
void Input (T &Ref)
{
...
}
std::string s;
int i;
float f;
Input(s);
Input(i);
Input(f);
template<class T>
void Input(T& ref)
{
..
}
Let me set the scene..
You can open files in a specific mode like this:
#include <fstream>
int main(){
std::fstream myfile;
myfile.open ("filename", std::ios::app);
return 0;
}
that second parameter is an enumerated type-
which is why you will get a compiler error attempting this:
#include <fstream>
int main(){
std::fstream myfile;
myfile.open ("filename", std::ios::lksdjflskdjflksff);
return 0;
}
In this example, the class doesn't have to account for the second parameter being incorrect, and the programmer never has to worry about passing in a nonsensical value.
Question: Is there a way to write functions that must take a particular type AND a particular value?
Let's say I wanted to re-implement a File Handling class similar to the one above.
The difference is I'm making the second parameter a char instead of an enumerated type.
How could I get something like this to work:
#include "MyFileHandler.h"
int main(){
MyFileHandler myfile1;
myfile.open ("filename", 'a'); //GOOD: a stands for append
myfile.open ("filename", 't'); //GOOD: t stands for truncate
myfile.open ("filename", 'x'); //COMPILER ERROR: openmode can not be the value 'x'
return 0;
}
Going beyond this, can I get the compiler to test the validity of argument values through functional means?
Example:
void IOnlyAcceptPrimeNumbers(const int & primeNumber);
int function(void);
int main(){
IOnlyAcceptPrimeNumbers(3); //GOOD: 3 is prime
IOnlyAcceptPrimeNumbers(7); //GOOD: 7 is prime
IOnlyAcceptPrimeNumbers(10); //COMPILER ERROR: 10 is not prime
IOnlyAcceptPrimeNumbers(10+1); //GOOD: 11 is prime
IOnlyAcceptPrimeNumbers(1+1+1+1); //COMPILER ERROR: 4 is not prime
IOnlyAcceptPrimeNumbers(function()); //GOOD: can this somehow be done?
return 0;
}
void IOnlyAcceptPrimeNumbers(const int & primeNumber){return;}
int function(void){return 7;}
I believe i've made it clear what I want to do and why I find it important.
Any solutions out there?
If you want compile-time checked values, you could write templates rather than function arguments:
template <char> void foo(std::string const &); // no implementation
template <> void foo<'a'>(std::string const & s) { /* ... */ }
template <> void foo<'b'>(std::string const & s) { /* ... */ }
Usage:
foo<'a'>("hello world"); // OK
foo<'z'>("dlrow olleh"); // Linker error, `foo<'z'>` not defined.
If you want an actual compiler error rather than just a linker error, you could add a static_assert(false) into the primary template.
No, if you specify that your function will take a char, it will take any char.
The "resolution" used by the compiler for checking passed arguments is the type rather than a set of possible values.
In other words, you need to use enumerations for this, or move the checking to runtime, or do something horrid like:
static void processAorT (char typ, char *fileName) { ... }
void processA (char *fileName) { processAorT ('a', fileName); }
void processT (char *fileName) { processAorT ('t', fileName); |
(not something I would advise, by the way).
Having said that, I'm not sure what you're proposing is a good idea anyway.
The compiler may be able to detect invalid constants, but won't be very successful if the parameter passed into IOnlyAcceptPrimeNumbers has come from a variable or, worse, input by a user.
The API is a contract between caller and function and, if the rules of that contract are not followed, you're free to do whatever you want, though hopefully you'd document it.
In other words, that function should begin:
void IOnlyAcceptPrimeNumbers (int num) {
if (!isPrime (num)) return;
// do something with a prime number.
}
(or the equivalent for your function that accepts a and t but not x). Doing nothing when passed invalid parameters is a reasonable strategy, as is returning an error or throwing an exception (though no doubt some would argue with this).
How you handle it is up to you, but it needs to be handled at runtime simply because the compiler doesn't have all the information.
You can only check value validity at runtime. Best you can do is use assert to stop programm execution if precondition is violated.
No. If you want to restrict the accepted arguments you need to use enums or accept an object that inherits from a specific interface (depends how sophisticated you want to make it). Enums is the common way to address this issue.
The example about the IOnlyAcceptPrimeNumbers is not well designed. If you want to achieve something similar it would be better to provide a class method that is something such as bool setNumber(int number) that will return false if the number is not prime. If you want to do it in the costructor the real alternative is to throw an exception (that is not really nice to do).
The concept is that you can not simply rely that the user will pass you only elements from a (correct) subset of the values that the parameter type allows.
While more restrictive than your requirements (this limits the values a particular type can hold), you can always try something like:
// Vowel.h
#ifndef VOWEL_H_
#define VOWEL_H_
class Vowel
{
public:
static const Vowel A;
static const Vowel E;
static const Vowel I;
static const Vowel O;
static const Vowel U;
char get() const { return value; }
private:
explicit Vowel(char c);
char value;
};
#endif /* VOWEL_H_ */
// Vowel.cpp
#include "Vowel.h"
Vowel::Vowel(char c) : value(c) {}
const Vowel Vowel::A('A');
const Vowel Vowel::E('E');
const Vowel Vowel::I('I');
const Vowel Vowel::O('O');
const Vowel Vowel::U('U');
Since the char constructor is private, only Vowel itself can construct objects from chars. All other uses are done by copy construction or copy assignment.
(I think I originally learned this technique from Scott Meyers; thank him / blame me.)
I am learning c++, and I just got to the object oriented chapter. I have a question about creating objects inside if statements.
The problem I'm working on says to create a class that will display a report header. The class has a default constructor that sets the company name and report name to a generic thing, and also, if the user wants, has a constructor that takes two arguments (strings company name and report name).
The problem says, specifically, "A two-parameter default constructor should allow these [company and report names] to be specified at the time a new Report object is created. If the user creates a Report object without passing any arguments, use the default values. Otherwise, use user specified values for the names."
So my question is, how to create these objects? I understand how to create an object without any arguments (i.e. Report newobj;), and also with arguments (i.e. Report newobj(string string);). Basically, I get how to create these objects initially at the top of my main function. But is it possible to create them inside if statements based on user choices? Here is what I have so far and, obviously, it doesn't work:
#include <iostream>
#include <string>
#include "report.h"
using namespace std;
bool enter_company_name(); // return true if user wants to enter company name
bool print_form(); // return true if user wants to print in formatted output
int main()
{
string company_name,
report_name;
bool name = false,
format = false;
name = enter_company_name();
format = print_form();
if (name)
{
cout << "Enter company name: ";
getline(cin, company_name);
cout << "Enter report name: ";
getline(cin, report_name);
Report header(company_name, report_name); // THIS IS MY PROBLEM
}
else
Report header; // THIS IS MY PROBLEM
if (format)
header.print_formatted();
else
header.print_one_line();
return 0;
}
bool enter_company_name()
{
char choice;
cout << "Do you want to enter a name?\n>";
cin >> choice;
if (choice == 'y' || choice == 'Y')
return true;
else
return false;
}
bool print_form()
{
char choice;
cout << "Do you want to print a formatted header?\n>";
cin >> choice;
if (choice == 'y' || choice == 'Y')
return true;
else
return false;
}
So I want to create an object using default values if none are specified, or create one with the user values if that's the choice given. I just can't figure out how to do it interactively in c++. I have not been able to find any similar questions anywhere so far.
The closest thing I've come across uses pointers to do something similar to what I want to do, but the book I'm using has not gotten to pointers yet, and I want to try to figure out a way to do it that stays within the bounds of the chapter I'm working in (i.e. not using pointers).
I didn't include the header file or class implementation file because I don't think they are relevant here.
Thank you in advance!
First off, you cannot create an object within a conditional statement and use it after the conditional statement: the two branches of the conditional statement create a scope each and any object created within in destroyed a the end of the branch. That is, you need to come up with a different approach. The simplest approach is probably to delegate the creation of the object to a function which returns the objects as appropriate:
Report makeReport() {
if (enter_company_name()) {
...
return Report(name, company);
}
return Report();
}
...
Report report = makeReport();
An alternative approach is to use the ternary operator to conditonally create the Report one way or another:
bool get_company_name = enter_company_name();
std::string name(get_company_name? read_name(): "");
std::string company(get_company_name? read_company(): "");
Report report = get_company_name? Report(name, company): Report();
All of these approaches assume that the Report class is actually copyable.
I don't know if I understood your question correctly but can't you just declare report before the if/else block and then initialize inside it?
Report header;
if (...) {
header = Report();
else
header = Report(name,company);
Or in a shorter way:
Report header; // calls default constructor
if (shouldInitializeWithParams) {
header = Report(name,company);
}
Of course this requires you to have the empty constructor defined.
We don't know whether class Report is copy-able, so better to use pointers.
Report * header;
if (...) {
header = new Report();
else
header = new Report(name,company);
// after all don't forget
delete header;
and of course you should use header pointer like that
header->print_formatted();
The simplest thing that comes to mind is performing a little refactoring on the code flow. Create a function that processes the input and returns the constructed object:
Report loadReport() {
if (user_input()) {
// read input
return Report(name,company);
} else {
return Report();
}
}
Then call the function from main. The small change in the design is the introduction of a function whose single responsibility is creating a Report from user input, which actually makes sense as a function.
You can use an rvalue reference to bind in place to either constructed object.
struct Foo
{
Foo(int bar): bar(bar) {}
int bar
};
Foo&& f = condition ? Foo(4) : Foo(5);
f.bar = 1000;
I'm not sure if I understood your question properly. Apologies if you read the answer and realise that that's the case.
But nevertheless, I think the main strategy would be to make use of constructor overloading. ie, you define constructors for both: the case when no parameters are passed and the case when parameters are passed.
The former(what you refer to as default constructor) will initialise the company and report names to default values. The latter will assign the parameters received, to the comapany and report names.
As for the use of pointers: you can avoid it by 'declaring' a lot of objects of type 'Report'(class). For eg, you can create an array of header(objects).
And then you can 'define' it as and when the user responds.
But by using pointers, you're doing everything in runtime(dynamic assignment) whereas when using arrays(or declaring many objects): the amount is fixed. This can be inefficient.
As of C++17, you can now use std::optional for this task - it avoids dynamic memory allocation, it avoids two-phase construction of the object, and it doesn't require the type to be movable or copyable. It allows you to delay the construction of the object while keeping it on the stack and also still being exception-safe. If you construct it in every branch you can safely use it afterward with no performance penalty. It will also work as a class member allowing you to avoid the problem with the class constructor initializer for it, unlike the rvalue reference solution. Demo: https://gcc.godbolt.org/z/vbe5eh
#include <optional>
struct UseCtorA final {};
struct UseCtorB final {};
struct Report final
{
Report() = delete;
Report(Report const &) = delete;
Report(Report &&) = delete;
Report &operator=(Report const &) = delete;
Report &operator=(Report &&) = delete;
Report(UseCtorA, char c) : v{1} { if(c == 't'){ throw 3; } }
Report(UseCtorB) : v{2} {}
constexpr auto getValue() const noexcept { return v; }
private:
int v;
};
int main(int nargs, char const *const *args)
{
std::optional<Report> report;
if(nargs > 2)
{
report.emplace(UseCtorA{}, args[1][0]);
}
else
{
report.emplace(UseCtorB{});
}
return report->getValue();
}
If you are stuck in an older compiler that only supports C++11, you can make your own really dumb version of std::optional for this express purpose by using a union and placement new:
struct Empty final {};
template<typename T>
struct Optional
{
Optional() noexcept : unused{} {}
~Optional() noexcept(noexcept(v.~T()))
{
if(constructed_successfully)
{
v.~T();
}
}
template<typename... Args>
auto emplace(Args &&... args) -> T &
{
if(constructed_successfully)
{
v.~T();
constructed_successfully = false;
}
T &r = *new (&v) T(std::forward<Args>(args)...);
constructed_successfully = true;
return r;
}
auto operator->() noexcept -> T *
{
return &v;
}
private:
union
{
T v;
[[no_unique_address]] Empty unused;
};
bool constructed_successfully = false;
};
The generated assembly is identical to with std::optional: https://gcc.godbolt.org/z/vzGz9E
Though, I would recommend using an existing library to supplement your lack of access to std::optional instead of rolling your own like I have done above - my version doesn't work for copying or moving.