Improvement for std::map double dispatch












6














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.










share|improve this question









New contributor




Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • 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
















6














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.










share|improve this question









New contributor




Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • 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














6












6








6


1





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.










share|improve this question









New contributor




Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











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++






share|improve this question









New contributor




Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 7 hours ago





















New contributor




Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 9 hours ago









Gasper J.

334




334




New contributor




Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Gasper J. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • 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




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










2 Answers
2






active

oldest

votes


















4














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)();
}
}





share|improve this answer























  • Instead of a lambda that calls the function you can use std::bind.
    – Emily L.
    6 hours ago



















0














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);





share|improve this answer





















  • 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











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.










draft saved

draft discarded


















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









4














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)();
}
}





share|improve this answer























  • Instead of a lambda that calls the function you can use std::bind.
    – Emily L.
    6 hours ago
















4














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)();
}
}





share|improve this answer























  • Instead of a lambda that calls the function you can use std::bind.
    – Emily L.
    6 hours ago














4












4








4






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)();
}
}





share|improve this answer














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)();
}
}






share|improve this answer














share|improve this answer



share|improve this answer








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


















  • 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













0














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);





share|improve this answer





















  • 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
















0














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);





share|improve this answer





















  • 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














0












0








0






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);





share|improve this answer












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);






share|improve this answer












share|improve this answer



share|improve this answer










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


















  • 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










Gasper J. is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

What visual should I use to simply compare current year value vs last year in Power BI desktop

Alexandru Averescu

Trompette piccolo