Pass multiple string functions into another function

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
getStr() returns something, you just never do anything (e.g display it on the screen) with the return value.
@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
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.
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:
 
return str;


Last edited on
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
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
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);
    }
};

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
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 cases 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
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
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
@againtry
Thank you! It all worked like a charm :)

@mbozzi
Thank you :)
@mbozzi

TheIdeasMan->ThingsLearnt++;

Will learn to read properly one day, I promise :+)
Topic archived. No new replies allowed.