Improvement for std::map double dispatch
I am trying to do my c++ homework and as a part of it I have to implement a std::map
with an int
as its key
and a value
should be a specific void
function, which prints some text.
I can`t find an answer to what are the correct ways of doing that.
This is what I have so far:
#include <map>
#include <string>
#include <iostream>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
typedef void(testClass::*runFunc)(void);
typedef std::map<int, runFunc> myMapType;
int main() {
testClass t1;
std::map<int, runFunc> myMap;
myMap.emplace(1, &testClass::testFunc1);
myMap.emplace(2, &testClass::testFunc2);
myMapType::const_iterator itr;
itr = myMap.find(2);
if (itr != myMap.end()) {
(t1.*(itr->second))();
}
}
The code is working now, however I am not sure if that is the way people with more experience do.
Also, if you are aware of any sources where one can read more about knowledge required to achieve the needed result - any ideas are appreciated.
c++
New contributor
add a comment |
I am trying to do my c++ homework and as a part of it I have to implement a std::map
with an int
as its key
and a value
should be a specific void
function, which prints some text.
I can`t find an answer to what are the correct ways of doing that.
This is what I have so far:
#include <map>
#include <string>
#include <iostream>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
typedef void(testClass::*runFunc)(void);
typedef std::map<int, runFunc> myMapType;
int main() {
testClass t1;
std::map<int, runFunc> myMap;
myMap.emplace(1, &testClass::testFunc1);
myMap.emplace(2, &testClass::testFunc2);
myMapType::const_iterator itr;
itr = myMap.find(2);
if (itr != myMap.end()) {
(t1.*(itr->second))();
}
}
The code is working now, however I am not sure if that is the way people with more experience do.
Also, if you are aware of any sources where one can read more about knowledge required to achieve the needed result - any ideas are appreciated.
c++
New contributor
If your code is a simplified version of what you really have to do, then it's off-topic and this question needs to be closed; per codereview.stackexchange.com/help/on-topic - "In order to give good advice, we need to see real, concrete code, and understand the context in which the code is used. Generic code (such as code containing placeholders like foo, MyClass, or doSomething()) leaves too much to the imagination."
– Reinderien
13 mins ago
add a comment |
I am trying to do my c++ homework and as a part of it I have to implement a std::map
with an int
as its key
and a value
should be a specific void
function, which prints some text.
I can`t find an answer to what are the correct ways of doing that.
This is what I have so far:
#include <map>
#include <string>
#include <iostream>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
typedef void(testClass::*runFunc)(void);
typedef std::map<int, runFunc> myMapType;
int main() {
testClass t1;
std::map<int, runFunc> myMap;
myMap.emplace(1, &testClass::testFunc1);
myMap.emplace(2, &testClass::testFunc2);
myMapType::const_iterator itr;
itr = myMap.find(2);
if (itr != myMap.end()) {
(t1.*(itr->second))();
}
}
The code is working now, however I am not sure if that is the way people with more experience do.
Also, if you are aware of any sources where one can read more about knowledge required to achieve the needed result - any ideas are appreciated.
c++
New contributor
I am trying to do my c++ homework and as a part of it I have to implement a std::map
with an int
as its key
and a value
should be a specific void
function, which prints some text.
I can`t find an answer to what are the correct ways of doing that.
This is what I have so far:
#include <map>
#include <string>
#include <iostream>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
typedef void(testClass::*runFunc)(void);
typedef std::map<int, runFunc> myMapType;
int main() {
testClass t1;
std::map<int, runFunc> myMap;
myMap.emplace(1, &testClass::testFunc1);
myMap.emplace(2, &testClass::testFunc2);
myMapType::const_iterator itr;
itr = myMap.find(2);
if (itr != myMap.end()) {
(t1.*(itr->second))();
}
}
The code is working now, however I am not sure if that is the way people with more experience do.
Also, if you are aware of any sources where one can read more about knowledge required to achieve the needed result - any ideas are appreciated.
c++
c++
New contributor
New contributor
edited 7 hours ago
New contributor
asked 9 hours ago
Gasper J.
334
334
New contributor
New contributor
If your code is a simplified version of what you really have to do, then it's off-topic and this question needs to be closed; per codereview.stackexchange.com/help/on-topic - "In order to give good advice, we need to see real, concrete code, and understand the context in which the code is used. Generic code (such as code containing placeholders like foo, MyClass, or doSomething()) leaves too much to the imagination."
– Reinderien
13 mins ago
add a comment |
If your code is a simplified version of what you really have to do, then it's off-topic and this question needs to be closed; per codereview.stackexchange.com/help/on-topic - "In order to give good advice, we need to see real, concrete code, and understand the context in which the code is used. Generic code (such as code containing placeholders like foo, MyClass, or doSomething()) leaves too much to the imagination."
– Reinderien
13 mins ago
If your code is a simplified version of what you really have to do, then it's off-topic and this question needs to be closed; per codereview.stackexchange.com/help/on-topic - "In order to give good advice, we need to see real, concrete code, and understand the context in which the code is used. Generic code (such as code containing placeholders like foo, MyClass, or doSomething()) leaves too much to the imagination."
– Reinderien
13 mins ago
If your code is a simplified version of what you really have to do, then it's off-topic and this question needs to be closed; per codereview.stackexchange.com/help/on-topic - "In order to give good advice, we need to see real, concrete code, and understand the context in which the code is used. Generic code (such as code containing placeholders like foo, MyClass, or doSomething()) leaves too much to the imagination."
– Reinderien
13 mins ago
add a comment |
2 Answers
2
active
oldest
votes
In general your code looks good. But I have some little annotations (improvements) for you.
1. I'd prefer direct initialization of itr
for sake of readability:
myMapType::const_iterator itr = myMap.find(2);
instead of
myMapType::const_iterator itr;
itr = myMap.find(2);
That said you could also avoid
typedef std::map<int, runFunc> myMapType;
completely using the auto
keyword:
auto itr = myMap.find(2);
2. Make use std::function
and lambda bindings
For the callable value parameter of the std::map
I'd prefer to use an appropriate std::function
value type and lambda function bindings to the instance to operate on.
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
This will give you greater flexibility for later changes and use of other classes than just testClass
. Also you can get rid of that other type definition then:
typedef void(testClass::*runFunc)(void);
As soon you want to use your map for the general case you can clearly see the benefits:
class A {
public:
void print() { std::cout << "print() from class A.n"; }
};
class B {
public:
void print() { std::cout << "print() from class B.n"; }
};
// ...
int main() {
A a;
B b;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&a](){a.print();});
myMap.emplace(2, [&b](){b.print();});
}
Here's my set of changes in whole (you can check it's still working as intended here):
#include <map>
#include <string>
#include <iostream>
#include <functional>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
int main() {
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
auto itr = myMap.find(2);
if (itr != myMap.end()) {
(itr->second)();
}
}
Instead of a lambda that calls the function you can use std::bind.
– Emily L.
6 hours ago
add a comment |
Given your current test code, there's no reason for testClass
to exist. Your two test functions can simply be functions in the global namespace, and then your emplace
calls can be simplified.
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
typedef void(*runFunc)(void);
// ...
myMap.emplace(1, testFunc1);
myMap.emplace(2, testFunc2);
thanks for your suggestion. my code above is a simplified version of what I really have to do. with just global functions it won't go.
– Gasper J.
3 hours ago
See comments on question, in that case. This is off-topic.
– Reinderien
12 mins ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Gasper J. is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210356%2fimprovement-for-stdmap-int-run-some-function-double-dispatch%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
In general your code looks good. But I have some little annotations (improvements) for you.
1. I'd prefer direct initialization of itr
for sake of readability:
myMapType::const_iterator itr = myMap.find(2);
instead of
myMapType::const_iterator itr;
itr = myMap.find(2);
That said you could also avoid
typedef std::map<int, runFunc> myMapType;
completely using the auto
keyword:
auto itr = myMap.find(2);
2. Make use std::function
and lambda bindings
For the callable value parameter of the std::map
I'd prefer to use an appropriate std::function
value type and lambda function bindings to the instance to operate on.
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
This will give you greater flexibility for later changes and use of other classes than just testClass
. Also you can get rid of that other type definition then:
typedef void(testClass::*runFunc)(void);
As soon you want to use your map for the general case you can clearly see the benefits:
class A {
public:
void print() { std::cout << "print() from class A.n"; }
};
class B {
public:
void print() { std::cout << "print() from class B.n"; }
};
// ...
int main() {
A a;
B b;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&a](){a.print();});
myMap.emplace(2, [&b](){b.print();});
}
Here's my set of changes in whole (you can check it's still working as intended here):
#include <map>
#include <string>
#include <iostream>
#include <functional>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
int main() {
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
auto itr = myMap.find(2);
if (itr != myMap.end()) {
(itr->second)();
}
}
Instead of a lambda that calls the function you can use std::bind.
– Emily L.
6 hours ago
add a comment |
In general your code looks good. But I have some little annotations (improvements) for you.
1. I'd prefer direct initialization of itr
for sake of readability:
myMapType::const_iterator itr = myMap.find(2);
instead of
myMapType::const_iterator itr;
itr = myMap.find(2);
That said you could also avoid
typedef std::map<int, runFunc> myMapType;
completely using the auto
keyword:
auto itr = myMap.find(2);
2. Make use std::function
and lambda bindings
For the callable value parameter of the std::map
I'd prefer to use an appropriate std::function
value type and lambda function bindings to the instance to operate on.
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
This will give you greater flexibility for later changes and use of other classes than just testClass
. Also you can get rid of that other type definition then:
typedef void(testClass::*runFunc)(void);
As soon you want to use your map for the general case you can clearly see the benefits:
class A {
public:
void print() { std::cout << "print() from class A.n"; }
};
class B {
public:
void print() { std::cout << "print() from class B.n"; }
};
// ...
int main() {
A a;
B b;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&a](){a.print();});
myMap.emplace(2, [&b](){b.print();});
}
Here's my set of changes in whole (you can check it's still working as intended here):
#include <map>
#include <string>
#include <iostream>
#include <functional>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
int main() {
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
auto itr = myMap.find(2);
if (itr != myMap.end()) {
(itr->second)();
}
}
Instead of a lambda that calls the function you can use std::bind.
– Emily L.
6 hours ago
add a comment |
In general your code looks good. But I have some little annotations (improvements) for you.
1. I'd prefer direct initialization of itr
for sake of readability:
myMapType::const_iterator itr = myMap.find(2);
instead of
myMapType::const_iterator itr;
itr = myMap.find(2);
That said you could also avoid
typedef std::map<int, runFunc> myMapType;
completely using the auto
keyword:
auto itr = myMap.find(2);
2. Make use std::function
and lambda bindings
For the callable value parameter of the std::map
I'd prefer to use an appropriate std::function
value type and lambda function bindings to the instance to operate on.
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
This will give you greater flexibility for later changes and use of other classes than just testClass
. Also you can get rid of that other type definition then:
typedef void(testClass::*runFunc)(void);
As soon you want to use your map for the general case you can clearly see the benefits:
class A {
public:
void print() { std::cout << "print() from class A.n"; }
};
class B {
public:
void print() { std::cout << "print() from class B.n"; }
};
// ...
int main() {
A a;
B b;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&a](){a.print();});
myMap.emplace(2, [&b](){b.print();});
}
Here's my set of changes in whole (you can check it's still working as intended here):
#include <map>
#include <string>
#include <iostream>
#include <functional>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
int main() {
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
auto itr = myMap.find(2);
if (itr != myMap.end()) {
(itr->second)();
}
}
In general your code looks good. But I have some little annotations (improvements) for you.
1. I'd prefer direct initialization of itr
for sake of readability:
myMapType::const_iterator itr = myMap.find(2);
instead of
myMapType::const_iterator itr;
itr = myMap.find(2);
That said you could also avoid
typedef std::map<int, runFunc> myMapType;
completely using the auto
keyword:
auto itr = myMap.find(2);
2. Make use std::function
and lambda bindings
For the callable value parameter of the std::map
I'd prefer to use an appropriate std::function
value type and lambda function bindings to the instance to operate on.
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
This will give you greater flexibility for later changes and use of other classes than just testClass
. Also you can get rid of that other type definition then:
typedef void(testClass::*runFunc)(void);
As soon you want to use your map for the general case you can clearly see the benefits:
class A {
public:
void print() { std::cout << "print() from class A.n"; }
};
class B {
public:
void print() { std::cout << "print() from class B.n"; }
};
// ...
int main() {
A a;
B b;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&a](){a.print();});
myMap.emplace(2, [&b](){b.print();});
}
Here's my set of changes in whole (you can check it's still working as intended here):
#include <map>
#include <string>
#include <iostream>
#include <functional>
class testClass
{
public:
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
};
int main() {
testClass t1;
std::map<int, std::function<void()>> myMap;
myMap.emplace(1, [&t1](){t1.testFunc1();});
myMap.emplace(2, [&t1](){t1.testFunc2();});
auto itr = myMap.find(2);
if (itr != myMap.end()) {
(itr->second)();
}
}
edited 6 hours ago
answered 8 hours ago
πάντα ῥεῖ
3,93031328
3,93031328
Instead of a lambda that calls the function you can use std::bind.
– Emily L.
6 hours ago
add a comment |
Instead of a lambda that calls the function you can use std::bind.
– Emily L.
6 hours ago
Instead of a lambda that calls the function you can use std::bind.
– Emily L.
6 hours ago
Instead of a lambda that calls the function you can use std::bind.
– Emily L.
6 hours ago
add a comment |
Given your current test code, there's no reason for testClass
to exist. Your two test functions can simply be functions in the global namespace, and then your emplace
calls can be simplified.
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
typedef void(*runFunc)(void);
// ...
myMap.emplace(1, testFunc1);
myMap.emplace(2, testFunc2);
thanks for your suggestion. my code above is a simplified version of what I really have to do. with just global functions it won't go.
– Gasper J.
3 hours ago
See comments on question, in that case. This is off-topic.
– Reinderien
12 mins ago
add a comment |
Given your current test code, there's no reason for testClass
to exist. Your two test functions can simply be functions in the global namespace, and then your emplace
calls can be simplified.
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
typedef void(*runFunc)(void);
// ...
myMap.emplace(1, testFunc1);
myMap.emplace(2, testFunc2);
thanks for your suggestion. my code above is a simplified version of what I really have to do. with just global functions it won't go.
– Gasper J.
3 hours ago
See comments on question, in that case. This is off-topic.
– Reinderien
12 mins ago
add a comment |
Given your current test code, there's no reason for testClass
to exist. Your two test functions can simply be functions in the global namespace, and then your emplace
calls can be simplified.
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
typedef void(*runFunc)(void);
// ...
myMap.emplace(1, testFunc1);
myMap.emplace(2, testFunc2);
Given your current test code, there's no reason for testClass
to exist. Your two test functions can simply be functions in the global namespace, and then your emplace
calls can be simplified.
void testFunc1() { std::cout << "func1n"; }
void testFunc2() { std::cout << "func2n"; }
typedef void(*runFunc)(void);
// ...
myMap.emplace(1, testFunc1);
myMap.emplace(2, testFunc2);
answered 4 hours ago
Reinderien
2,704619
2,704619
thanks for your suggestion. my code above is a simplified version of what I really have to do. with just global functions it won't go.
– Gasper J.
3 hours ago
See comments on question, in that case. This is off-topic.
– Reinderien
12 mins ago
add a comment |
thanks for your suggestion. my code above is a simplified version of what I really have to do. with just global functions it won't go.
– Gasper J.
3 hours ago
See comments on question, in that case. This is off-topic.
– Reinderien
12 mins ago
thanks for your suggestion. my code above is a simplified version of what I really have to do. with just global functions it won't go.
– Gasper J.
3 hours ago
thanks for your suggestion. my code above is a simplified version of what I really have to do. with just global functions it won't go.
– Gasper J.
3 hours ago
See comments on question, in that case. This is off-topic.
– Reinderien
12 mins ago
See comments on question, in that case. This is off-topic.
– Reinderien
12 mins ago
add a comment |
Gasper J. is a new contributor. Be nice, and check out our Code of Conduct.
Gasper J. is a new contributor. Be nice, and check out our Code of Conduct.
Gasper J. is a new contributor. Be nice, and check out our Code of Conduct.
Gasper J. is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210356%2fimprovement-for-stdmap-int-run-some-function-double-dispatch%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
If your code is a simplified version of what you really have to do, then it's off-topic and this question needs to be closed; per codereview.stackexchange.com/help/on-topic - "In order to give good advice, we need to see real, concrete code, and understand the context in which the code is used. Generic code (such as code containing placeholders like foo, MyClass, or doSomething()) leaves too much to the imagination."
– Reinderien
13 mins ago