Is this code legal in ISO C++? - c++

So I'm trying to implement function parameters which can be uninitialized. Here is the code which I have written. My question is if it's legal by the ISO C++ standard (version 14 if possible).
#include <iostream>
#include <typeinfo>
using namespace std;
template<typename type>
struct nzeroinittmpliteral
{
nzeroinittmpliteral() { }
nzeroinittmpliteral(type arg) { d = arg; }
//nzeroinittmpliteral(const nzeroinittmpliteral &) = delete;
operator type () & { return d; }
operator type () && { return d; }
type d;
} ;
void func(bool bIsPointerValid, nzeroinittmpliteral<int *> pVar = {})
{
if(bIsPointerValid)
{
cout << *pVar << endl;
}
else
{
pVar = new int;
*pVar = 8;
cout << *pVar << endl;
delete pVar;
}
}
int main()
{
func(true, { (int *)&(const int &)int{9} } );
func(false);
}

If you want to pass a parameter that may be uninitialized, simply don't pass it, use overloading. Look:
void func(int value)
{
cout << value << endl;
}
void func()
{
// no 'value' was initialized here :)
func(8);
}
Or simply give a default value to the parameter if you will provide one anyway in your body:
void func(int value = 8)
{
cout << value << endl;
}
Besides that, you can take a look at boost::optional:
void func(boost::optional<int> optvalue = boost::none) {
if (optvalue) {
cout << *optvalue << endl;
} else {
// nothing passed
cout << "foo" << endl;
}
}
Directly answering your question: your code is valid.
func(true, { (int *)&(const int &)int{9} } );
By casting the temporary to a const reference, you extend its lifetime to the lifetime of the reference itself, which ends after func returns. But this is too redundant, you could simply have written:
void func(int* value) { if (value) {...} }
func(&(const int &)9);
func(nullptr);
The actual parameter being passed is your nzeroinittmpliteral and it is initialized by calling one of the constructors, always. The default constructor doesn't initialize the d member, but this is no big improvement as it is just a pointer. Using nullptr is better and removes the need for the bool parameter.

Related

How do you call a function from a pointer array to a class method in C++? [duplicate]

This question already has answers here:
C++ Call Pointer To Member Function
(4 answers)
Closed 1 year ago.
I'm pretty new to C++
I have this code:
in my class.hpp
class Dummy {
private:
void f1(void);
void f2(void);
void f3(void);
void f4(void);
public:
void caller(std::string id);
};
in my class.cpp
void Dummy::caller( std::string id ) {
// something something about qualifiers requires Dummy::*f instead of just *f
void (Dummy::*f[4])() = {&Dummy::f1, &Dummy::f2, &Dummy::f3, &Dummy::f4};
string v[4] = {"f1", "f2", "f3", "f4"};
for (int i = 0; i < 4; i++) {
if (id == v[i]) {
(*f[i])();
break ;
}
}
}
this (*f[i])() is valid in C code, but for some reason in C++, it shows me this error which i googled but was unlucky and found nothing that useful, except for std::invoke which is in C++17 (?), and I'm bound to C++98
The error:
Class.cpp:41:5: error: indirection requires pointer operand ('void (Dummy::*)()' invalid)
(*f[i])();
^~~~~
well, this is not how c++ works...
just because you define functions like
void f1(void);
void f2(void);
void f3(void);
void f4(void);
doesnt mean you can access them or handle then like you were working with an array
but that is the key to solve that,
you can create an array of functions and call it by index
here is a short example of how you can achieve that:
#include <iostream>
void f1(void)
{
std::cout << "you are in f1" << std::endl;
}
void f2(void)
{
std::cout << "you are in f2" << std::endl;
}
void f3(void)
{
std::cout << "you are in f3" << std::endl;
}
void f4(void)
{
std::cout << "you are in f4" << std::endl;
}
void (*p[4]) (void);
int main(void)
{
int result;
int i, j, op;
p[0] = f1;
p[1] = f2;
p[2] = f3;
p[3] = f4;
for(auto i= 0; i<4; ++i)
{
(*p[i])();
}
return 0;
}

C++ A function that can return one of two types depending on the accepted value

fun(int a) {
if (a) return a; return "empty";
}
I need a function that gets a number and depending on which number it is returns either an int variable or a string.
Please tell me how I can implement such a function.
With C++ 17 you can use variant:
std::variant<int, std::string> fun(int a) {
if (a) return a; return "empty";
}
Or use a struct with optional:
struct r {
std::optional<int> i;
std::optional<std::string> s;
};
r fun(int a) {
r out;
if (a) out.i = a; else out.s = "empty";
return out;
}
Or for prior standards use a struct with fields indicating validity.
struct r {
enum class type {i, s};
int i;
std::string s;
type t;
};
r fun(int a) {
r out;
if (a) {
out.i = a;
out.t = r::type::i;
else {
out.s = "empty";
out.t = r::type::s;
}
return out;
}
Interpret-able languages like python does not have restrictions on type of argument and type of return value. However, C++ can only accept and return values of pre-defined type.
Now, Adding to other answers, if you don't have C++17, You could try it this way:
std::pair<int, string> func(int a)
{
if(a) return std::make_pair(a , "");
return std::make_pair(0,"string");
}
In callee, you can check for non-null against both members of std::pair.
You could accomplish this flow with exceptions! If func is expecting to work with a number that is greater than 5, for example, you could do something like:
int func(int a) {
if (a > 5) { return a; }
throw std::runtime_error("Empty");
}
int main() {
try {
int x = func(3);
// Do some stuff with x...
} catch(const std::exception &e) {
std::cout << "Looks like the num is " << e.what();
}
}
So you either process the int if things went well, or, if something bad happened, you grab the string from the exception and deal with it.
You could accomplish this by splitting the two different tasks into separate functions and continue your execution from there.
#include <iostream>
using namespace std;int inputValue = 0;
int returnInt() {
std::cout << "Returning your int" << std::endl;
return inputValue;
}
string returnString() {
std::cout << "Returning your string" << std::endl;
return "Your string";
}
int main() {
std::cout << "Please type in a number" << "\t";
std::cin >> inputValue;
if (inputValue > 5) {
returnInt();
}
else {
returnString();
}
}

Return a function from a class

I want to be able to return a function from a class, so that I do not need to if-else through a return type.
I have a class that returns multiple strings. Instead, I want to return multiple functions.
#include <iostream>
class Handler
{
private:
public:
int handleMessage(int code)
{
return code+1;
}
};
void func1();
void func2();
void func3();
int main (int argc, char *argv[])
{
Handler handle;
int code = handle.handleMessage(0);
if(code == 1)
{
func1();
}
return 0;
}
void func1(){ std::cout << "1" << std::endl;}
void func2(){ std::cout << "2" << std::endl;}
void func3(){ std::cout << "3" << std::endl;}
What I want is: That the function handleMessage in the class Handler returns something so that in my main application I do not have to use if-else.
So the main looks like this:
function = handle.handleMessage(0);
And the application will choose which function it will run.
for example:
function = handle.handleMessage(0); //will run func1
function = handle.handleMessage(1); //will run func2
You can modify the member function such that it returns a function pointer, e.g.
using fptr = void (*)();
struct Handler
{
fptr handleMessage (int code)
{
if (code == 0)
return &func1;
else if (code == 1)
return &func2;
else
return &func3;
}
};
This can be invoked as follows
Handler handle;
auto f = handle.handleMessage(0);
f();
Note that the above if-else if-else dispatch isn't ideal. Prefer a data member that stores the function pointers and associates them with a code, e.g. using a std::unordered_map.
Note that when you need to return stateful function objects in the future, this approach will fail. Then, you need to embrace std::function which is able to wrap lambdas with closures or custom types with an operator() overload.
There are several ways to do so, the simplest one, you can use an std::function. In this example we returning a lambda function for each case. You can replace it with the functions you just wrote.
class Handler {
public:
std::function<void()> handleMessage(int code) {
code = code + 1; // ++code or whatever
if (code == X) {
return []() { std::cout << "Cool! I'am x!" << std::endl; };
} else if (code == Y) {
return []() { std::cout << "Cool! I'am x!" << std::endl; };
} else if (...) {
...
} else {
....
}
}
};
Then your main function becomes:
int main (int argc, char *argv[]) {
Handler handle;
const auto func = handle.handleMessage(0);
func();
return 0;
}
You can replace the swith/if case statement by an array storing the different functions, like they mentioned in the comments.
If you dont want to pay the extra virtual function call regarding the usage of an std::function, you can use an alias like the answer below or just the auto keyword:
class Handler {
public:
constexpr auto handleMessage(int code) {
code = code + 1; // ++code or whatever
if (code == X) {
return &func1;
} else if (code == Y) {
return &func2;
} else if (...) {
...
} else {
....
}
}
};
std::function is a powerful tool. The tiny brother is a simple function pointer.
I transformed MCVE respectively to return a function pointer:
#include <iostream>
typedef void (*FuncPtr)();
void func1();
void func2();
void func3();
void funcError();
class Handler
{
private:
public:
FuncPtr handleMessage(int code)
{
switch (code + 1) {
case 1: return &func1;
case 2: return &func2;
case 3: return &func3;
default: return &funcError;
}
}
};
int main (int argc, char *argv[])
{
Handler handle;
FuncPtr pFunc = handle.handleMessage(0);
pFunc();
return 0;
}
void func1(){ std::cout << "1" << std::endl;}
void func2(){ std::cout << "2" << std::endl;}
void func3(){ std::cout << "3" << std::endl;}
void funcError(){ std::cout << "ERROR!" << std::endl;}
Output:
1
Live Demo on coliru
You can return a function with return_type(*function_name)(argument_type1, argument_type2...) so a function that looks like:
double f(int a, int b);
has the name double(*f)(int, int).
Worth mentioning is C++11's std::function which requires the <functional> header. It has a more intuitive usage: std::function<double(int, int)> but also adds a bit of overhead.
I would also like to suggest the usage of C++17's std::optional as for the case when the variable code goes out of bounds. This implementation requires the <optional> header.
std::optional<void(*)()> handleMessage(int code){
switch (code) {
case 0: return std::optional(func1);
case 1: return std::optional(func2);
case 2: return std::optional(func3);
}
return std::nullopt; //empty
}
usage in main looks like the following:
Handler handle;
auto func = handle.handleMessage(0);
if (func.has_value()) {
func.value()();
}
as this allows to check if func.has_value() which is quite convenient.
Use an array of functions.
void func1(){ std::cout << "1" << std::endl; }
void func2(){ std::cout << "2" << std::endl; }
void func3(){ std::cout << "3" << std::endl; }
typedef void (* func ) () ;
class Handler {
public:
func handleMessage(int code)const{
static const func F[] = { func1, func2, func3 };
return F[ code ];
}
};
int main()
{
Handler handler;
func f = handler.handleMessage(0); // returns func1
f();
}
live example
you can map the ints to a function or lambda, but read befor what at() does and what happens if the key is not found!!
void function1()
{
std::cout << "q1" << std::endl;
}
void function2()
{
std::cout << "q2" << std::endl;
}
int main(int argc, char* argv[])
{
std::map<int, std::function<void(void)>> map;
map.insert(std::make_pair(1, function1));
map.insert(std::make_pair(1, function2));
map.at(1)();
I would like to offer solution without any if-else block. You just need to templatize your Handler::handleMessage function. Something like this:
// Class declaration
class Handler
{
private:
public:
template<int code>
void handleMessage();
};
and specialize the function template for particular codes:
// Function template specializations.
template<>
void Handler::handleMessage<1>()
{
std::cout << "1" << std::endl;
}
template<>
void Handler::handleMessage<2>()
{
std::cout << "2" << std::endl;;
}
template<>
void Handler::handleMessage<3>()
{
std::cout << "3" << std::endl;;
}
// All cases, except 1, 2 and 3
template<int code>
void Handler::handleMessage()
{
std::cout << "Anything else" << std::endl;;
}
The usage may look like:
Handler h;
h.handleMessage<1>(); // Prints 1
h.handleMessage<2>(); // Prints 2
h.handleMessage<3>(); // Prints 3
h.handleMessage<323>(); // Prints 'Anything else'

How to access a dynamic object property not using getter method?

#include <iostream>
class SomeClass
{
public: int *SomeNumber;
SomeClass() { SomeNumber = new int; *SomeNumber = 5; }
~SomeClass() { delete SomeNumber; }
int getSomeNumber(void) { return *SomeNumber; }
};
int main()
{
SomeClass A;
std:: cout << A.getSomeNumber() << std::endl; // outputs 5
std:: cout << A.SomeNumber << std::endl; // outputs SomeNumber address
return 0;
}
How can I get *SomeNumber, not its address, by not using the method getSomeNumber()? If SomeNumber were not a pointer to a int, I could get it with A.SomeNumber
Sorry If I were not clear enough.
Thanks in advance.
Simple:
*A.SomeNumber
It works because . has higher precedence than *, so it's the same as
*(A.SomeNumber)
Can't you just do:
std:: cout << (*A.SomeNumber) << std::endl;
Avoid making your properties public!!!!
You could use visitor design pattern instead of this code like:
class SomeClass
{
public: int *SomeNumber;
SomeClass() { SomeNumber = new int; *SomeNumber = 5; }
void visit( IVisitor* visitor ){ visitor->doSomething(*SomeNumber);}
~SomeClass() { delete SomeNumber; }
int getSomeNumber(void) { return *SomeNumber; }
};
IVisitor is an interface you can implement it and anything you want.

C++ function pointer (class member) to non-static member function

class Foo {
public:
Foo() { do_something = &Foo::func_x; }
int (Foo::*do_something)(int); // function pointer to class member function
void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; }
private:
int func_x(int m) { return m *= 5; }
int func_y(int n) { return n *= 6; }
};
int
main()
{
Foo f;
f.setFunc(false);
return (f.*do_something)(5); // <- Not ok. Compile error.
}
How can I get this to work?
class A{
public:
typedef int (A::*method)();
method p;
A(){
p = &A::foo;
(this->*p)(); // <- trick 1, inner call
}
int foo(){
printf("foo\n");
return 0;
}
};
void main()
{
A a;
(a.*a.p)(); // <- trick 2, outer call
}
The line you want is
return (f.*f.do_something)(5);
(That compiles -- I've tried it)
"*f.do_something" refers to the pointer itself --- "f" tells us where to get the do_something value from. But we still need to give an object that will be the this pointer when we call the function. That's why we need the "f." prefix.
class A {
int var;
int var2;
public:
void setVar(int v);
int getVar();
void setVar2(int v);
int getVar2();
typedef int (A::*_fVar)();
_fVar fvar;
void setFvar(_fVar afvar) { fvar = afvar; }
void insideCall() { (this->*fvar)(); }
};
void A::setVar(int v)
{
var = v;
}
int A::getVar()
{
std::cout << "A::getVar() is called. var = " << var << std::endl;
return var;
}
void A::setVar2(int v2)
{
var2 = v2;
}
int A::getVar2()
{
std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl;
return var2;
}
int main()
{
A a;
a.setVar(3);
a.setVar2(5);
// a.fvar = &A::getVar;
a.setFvar(&A::getVar);
(a.*a.fvar)();
a.setFvar(&A::getVar2);
(a.*a.fvar)();
a.setFvar(&A::getVar);
a.insideCall();
a.setFvar(&A::getVar2);
a.insideCall();
return 0;
}
I extended Nick Dandoulakis's answer. Thank you.
I added a function which set the member function pointer from outside of the class. I added another function which can be called from outside to show inner call of member function pointer.
Try (f.*do_something)(5);
#include<iostream>
using namespace std;
class A {
public:
void hello()
{
cout << "hello" << endl;
};
int x = 0;
};
void main(void)
{
//pointer
A * a = new A;
void(A::*pfun)() = &A::hello;
int A::*v1 = &A::x;
(a->*pfun)();
a->*v1 = 100;
cout << a->*v1 << endl << endl;
//-----------------------------
A b;
void(A::*fun)() = &A::hello;
int A::*v2 = &A::x;
(b.*fun)();
b.*v2 = 200;
cout << b.*v2 << endl;
}
I think calling a non static member of the class could also be done using a static member function.