Pass multiple string functions into another function
May 14, 2021 at 7:13pm UTC
Can anyone tell me why this code is not returning anything?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#include <iostream>
#include <functional>
std::string getHi(){
std::string hi = "Hi " ;
return hi;
}
std::string getName(){
std::string nam = "Jack!" ;
return nam;
}
std::string getStr(std::string(&h)(),std::string(&n)())
{
std::string str = h() + n();
return str;
}
int main()
{
getStr(getHi,getName);
return 0;
}
Also, please show declaration in .h and implementation in .cpp of how to create a function which gets multiple different functions, concatenate and then return them as single string?
Last edited on May 14, 2021 at 7:16pm UTC
May 14, 2021 at 7:28pm UTC
getStr() returns something, you just never do anything (e.g display it on the screen) with the return value.
May 14, 2021 at 7:34pm UTC
@helios
Oh, no...I'm quite tired today!! Thank you :)
Can you tell how the declaration should be in header file? I did this but VS gives me C2511 error?!
.h file:
std::string getStr(std::string&, std::string&);
.cpp
1 2 3 4 5
std::string myClass::getStr(std::string(&h)(),std::string(&n)())
{
std::string str = h() + n();
std::cout << str;
}
Last edited on May 14, 2021 at 7:43pm UTC
May 14, 2021 at 7:54pm UTC
Declaration:
std::string getStr(std::string(&h)(), std::string(&n)());
You can also omit the parameter names:
std::string getStr(std::string(&)(), std::string(&)());
Note that the latest version of getStr() you posted is incorrect. Calling a non-void function that doesn't return anything causes undefined behavior, if I'm not mistaken.
May 14, 2021 at 8:31pm UTC
Thanks. But I still can't get it work on the main function getting errors such as :
"a pointer to a bound function may only be used to call the function"
"initial value of reference to non-const must be an lvalue"
so in main I did this:
1 2 3 4 5 6 7 8
myClass c1;
c1.setHi();
c1.setName();
std::cout << c1.getStr(c1.getHi,c1.getName);
Note that the latest version of getStr() you posted is incorrect. Calling a non-void function that doesn't return anything causes undefined behavior, if I'm not mistaken.
Okay, I changed it to:
Last edited on May 14, 2021 at 8:34pm UTC
May 14, 2021 at 9:00pm UTC
Non-static member functions work entirely differently from global functions when it comes to getting pointers and references to them and when calling those pointers and references. I'm not 100% sure, but I think the correct syntax would be
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class A{
std::string foo(){
return "foo" ;
}
std::string bar(){
return "bar" ;
}
public :
std::string f(std::string (A::&some_function)()){
return (this ->some_function)() + "!" ;
}
std::string g(){
return this ->f(A::foo) + " + " + this ->f(A::bar);
}
};
Last edited on May 14, 2021 at 9:01pm UTC
May 14, 2021 at 11:22pm UTC
I couldn't get it to work after some search for Error C3867. Here's simple version of .h, .cpp and main. Please see if you can spot the mistake(s):
.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
class myClass1
{
public :
myClass1();
myClass1(std::string,std::string);
~myClass1();
std::string getHi() const ;
std::string getName() const ;
std::string setHi() const ;
std::string setName() const ;
Private:
std::string newHi;
std::string newName;
}
class myClass2 : public myClass1
{
public :
myClass2();
myClass2(std::string);
~myClass2();
std::string getText();
std::string setText();
std::string getStr(std::string(&h)(), std::string(&n)(), std::string(&t)());
Private:
std::string newText;
}
.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
myClass1::myClass1() {};
myClass1::myClass1(std::string hi,std::string name)
{
newHi = hi;
newName = name;
}
myClass1::~myClass1() {};
std::string myClass1::getHi()
{
return newHi;
}
std::string myClass1::getName()
{
return newName;
}
std::string myClass1::setHi()
{
std::string h = "Hi " ;
newHi = h;
}
std::string myClass1::setName()
{
std::string n = "Jack!" ;
newHi = n;
}
myClass2:
myClass2() {};
myClass2::myClass2(std::string text)
{
newText = text;
}
myClass2::~myClass2() {};
std::string myClass2::getText()
{
return newText;
}
std::string myClass2::setText()
{
std::string text;
cout << "Type the body of Letter: " << endl;
cin >> text;
newText = text;
}
std::string myClass2::getStr(std::string(&h)(), std::string(&n)(), std::string(&t)())
{
std::string Letter = h() + n() + t();
return Letter;
};
main()
1 2 3 4 5 6 7 8 9 10 11 12 13
int main()
{
myClass2 c2;
c2.setHi();
c2.setName();
c2.setText();
cout << c2.getStr(c2.getHi, c2.getName, c2.getText);
return 0;
}
Last edited on May 14, 2021 at 11:28pm UTC
May 15, 2021 at 12:29am UTC
I'm not 100% sure, but I think the correct syntax would be
There's no such thing as a reference-to-member but otherwise it's just a matter of syntax:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class A{
std::string foo(){
return "foo" ;
}
std::string bar(){
return "bar" ;
}
public :
std::string f(std::string (A::*some_function)()){
return (this ->*some_function)() + "!" ;
}
std::string g(){
return this ->f(&A::foo) + " + " + this ->f(&A::bar);
}
};
May 15, 2021 at 12:57am UTC
Hello hdcpp64,
How about the simple approach:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include <iostream>
#include <functional>
std::string getHi(){
std::string hi = "Hi " ;
return hi;
}
std::string getName(){
std::string nam = "Jack!" ;
return nam;
}
std::string getStr(std::string(&h)(),std::string(&n)())
{
std::string str = h() + n();
return str;
}
int main()
{
std::cout << getStr(getHi,getName);
return 0;
}
Andy
May 15, 2021 at 4:31am UTC
Hi,
With C++17, one can use the
[[nodiscard]]
attribute, to make the compiler complain about discarded results from function calls.There are others like
[[noreturn]]
for functions whose return type is
void
. And
[[fallthrough]]
for intentional falling through
case
s in a
switch
statement.
https://en.cppreference.com/w/cpp/language/attributes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#include <iostream>
#include <functional>
[[nodiscard]]
std::string getHi(){
std::string hi = "Hi " ;
return hi;
}
[[nodiscard]]
std::string getName(){
std::string nam = "Jack!" ;
return nam;
}
[[nodiscard]]
std::string getStr(std::string(&h)(),std::string(&n)())
{
std::string str = h() + n();
return str;
}
int main()
{
//std::cout << getStr(getHi,getName);
getStr(getHi,getName);
return 0;
}
g++ -std=c++17 -Wall -Wextra test4.cpp -o test4
test4.cpp: In function ‘int main()’:
test4.cpp:25:22: warning: ignoring return value of ‘std::string getStr(std::string (&)(), std::string (&)())’, declared with attribute ‘nodiscard’ [-Wunused-result]
25 | getStr(getHi,getName);
| ^
test4.cpp:16:13: note: declared here
16 | std::string getStr(std::string(&h)(),std::string(&n)())
Last edited on May 15, 2021 at 4:35am UTC
May 15, 2021 at 5:48am UTC
This runs but it has a lot of tidy up problems.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#include <string>
#include <iostream>
class myClass1
{
private :
std::string newHi;
std::string newName;
public :
myClass1();
myClass1(std::string,std::string);
~myClass1();
std::string getHi();
std::string getName();
void setHi();
void setName();
};
myClass1::myClass1() {};
myClass1::myClass1(std::string hi,std::string name)
{
newHi = hi;
newName = name;
}
myClass1::~myClass1() {};
std::string myClass1::getHi()
{
return newHi;
}
std::string myClass1::getName()
{
return newName;
}
void myClass1::setHi()
{
std::string h = "Hi " ;
newHi = h;
}
void myClass1::setName()
{
std::string n = "Jack!" ;
newName = n;
}
class myClass2 : public myClass1
{
public :
myClass2();
myClass2(std::string);
~myClass2();
std::string getText();
void setText();
std::string getStr(std::string, std::string, std::string);
private :
std::string newText;
};
myClass2::myClass2() {};
myClass2::myClass2(std::string text)
{
newText = text;
}
myClass2::~myClass2() {};
std::string myClass2::getText()
{
return newText;
}
void myClass2::setText()
{
std::string text;
std::cout << "Type the body of Letter: \n" ;
std::cin >> text;
newText = text;
}
std::string myClass2::getStr(std::string h, std::string n, std::string t)
{
std::string Letter = h + n + t;
return Letter;
}
int main()
{
myClass2 c2;
c2.setHi();
c2.setName();
c2.setText();
std::cout << c2.getStr(c2.getHi(), c2.getName(), c2.getText()) << '\n' ;
return 0;
}
Type the body of Letter:
this is a letter
Hi Jack!this
Program ended with exit code: 0
May 15, 2021 at 6:52am UTC
There are others like [[noreturn]] for functions whose return type is void
[[noreturn]] is intended for functions like
std::exit which never return at all, or functions which enter an infinite loop with side-effects. The idea is that the additional information can aid the compiler optimizer, or help the compiler warn the programmer about unreachable code.
[[nodiscard]] makes software less wrong. Few features offer such an immediate and major improvement to product quality. Use it!
Last edited on May 15, 2021 at 6:54am UTC
May 15, 2021 at 7:37am UTC
@againtry
Thank you! It all worked like a charm :)
@mbozzi
Thank you :)
May 15, 2021 at 9:16am UTC
@mbozzi
TheIdeasMan->ThingsLearnt++;
Will learn to read properly one day, I promise :+)
Topic archived. No new replies allowed.