I have the following code and I want to know how duplicate issue for lines 33-38 with 47-52 cand be solved.
struct X has 2 methods with same signature and Y has an instance of X and has 2 methods which has to use the same callback which has to capture same values for the methods from X.
#include <iostream>
#include <functional>
using namespace std;
struct X
{
void func(std::function<void(int)>f, int x)
{
f(x);
}
void func2(std::function<void(int)>f, int x)
{
f(x);
}
};
struct Y
{
void doSomething_1()
{
int x = 10;
bool called = false;
x_.func(
[&x, &called](int xx) // line 33
{ // line 34
called = true; // line 35
x++; // line 36
xx++; // line 37
} // line 38
, 20);
}
void doSomething_2()
{
int x = 10;
bool called = false;
x_.func2(
[&x, &called](int xx) // line 47
{ // line 48
called = true; // line 49
x++; // line 50
xx++; // line 51
} // line 52
, 20);
}
X x_;
};
int main()
{
Y y;
y.doSomething_1();
y.doSomething_2();
return 0;
}
How about The Standard Solution – add a level of indirection?
struct Y
{
void doSomething_1()
{
int x = 10;
bool called = false;
x_.func([this, &x, &called](int xx) { wrapper(x, called, xx); }, 20);
}
void doSomething_2()
{
int x = 10;
bool called = false;
x_.func([this, &x, &called](int xx) { wrapper(x, called, xx); }, 20);
}
X x_;
void wrapper(int&x, bool& called, int xx) { called = true; x++; xx++; }
};
or
struct Y
{
void doSomething_1()
{
int x = 10;
bool called = false;
x_.func(wrapper(x, called), 20);
}
void doSomething_2()
{
int x = 10;
bool called = false;
x_.func(wrapper(x, called), 20);
}
X x_;
std::function<void(int)> wrapper(int&x, bool& called)
{
return [&x, &called](int xx) {called = true; x++; xx++; };
};
};
It is a little bit more difficult than expected, because you are capturing different variables in the 2 functions.
You can use std::bind with a function for that:
#include <iostream>
#include <functional>
using namespace std;
struct X
{
void func(std::function<void(int)>f, int x)
{
f(x);
}
void func2(std::function<void(int)>f, int x)
{
f(x);
}
};
void your_func(int xx, bool &called, int &x)
{
called = true;
x++;
xx++;
}
struct Y
{
void doSomething_1()
{
int x = 10;
bool called = false;
auto func = std::bind(&your_func, std::placeholders::_1, called, x);
x_.func(func, 20);
}
void doSomething_2()
{
int x = 10;
bool called = false;
auto func = std::bind(&your_func, std::placeholders::_1, called, x);
x_.func2(func, 20);
}
X x_;
};
int main()
{
Y y;
y.doSomething_1();
y.doSomething_2();
return 0;
}
https://godbolt.org/z/5ee5ehcsh
You can also std::bind to a member function: https://godbolt.org/z/f9snPbKeW
I must admit that I always hated things like bind() since I learnt them first in combination with sigc++. (I never could remember the correct order to apply them, especially if combined with hide().)
With the introduction of lambdas, all the trouble was gone immediately (and I soon became a fan of lambdas).
A lambda in turn just resembles a function or functor. So, to add to mch's answer, the lambda could be turned into a re-usable functor which is embedded into OPs class Y:
#include <iostream>
#include <functional>
using namespace std;
struct X
{
void func(std::function<void(int)>f, int x)
{
f(x);
}
void func2(std::function<void(int)>f, int x)
{
f(x);
}
};
struct Y
{
struct Count {
int& x;
bool& called;
Count(int& x, bool& called): x(x), called(called) { }
void operator()(int xx) // line 33
{ // line 34
called = true; // line 35
x++; // line 36
xx++; // line 37
}
};
void doSomething_1()
{
int x = 10;
bool called = false;
x_.func(Count(x, called), 20);
}
void doSomething_2()
{
int x = 10;
bool called = false;
x_.func2(Count(x, called), 20);
}
X x_;
};
int main()
{
Y y;
y.doSomething_1();
y.doSomething_2();
return 0;
}
Live Demo on coliru
Related
Consider the following example:
func(cond, block_A, block_B) {
if(cond) {
block_A; // Run all the statements in the block A
} else {
block_B; // Run all the statements in the block B
}
}
int main() {
block_A = {
y = 1;
std::cout << (y);
// statement continues ...
}
block_B = {
z = 1;
std::cout << (z);
// statement continues ...
}
func(true, block_A, block_C);
}
Is there any way to pass a block of statements as an argument to the function call?
You can pass callables to func and use lambda expressions:
#include <iostream>
template <typename F,typename G>
void func(bool cond, F a, G b) {
if(cond) {
a(); // Run all the statements in the block A
} else {
b(); // Run all the statements in the block B
}
}
int main() {
auto block_A = [](){
int y = 1;
std::cout << y;
};
auto block_B = [](){
int z = 1;
std::cout << z;
};
func(true, block_A, block_B);
}
I am creating a C++ class which takes certain parameters during initialization and has some functions based on its private variables, something like the compute function here:
class A {
public:
A(int x){
a = x;
}
int compute(int y){
if (a == 0){
return y*y;
}
else if (a == 1){
return 2*y;
}
else{
return y;
}
}
private:
int a;
};
// usage
A myA(1); // private variables set only once
myA.compute(10); // this will check value of a
myA.compute(1); // this will check value of a
Given that the private variables are set during initialization and will not be changed again, is there any efficient way to avoid the condition check related to the private variables during runtime?
Any and all assistance is appreciated. Thank you
You can template the function compute() on an int and use the template value as parameter. You can see the result at https://godbolt.org/z/14Mh4E
class A {
public:
A(int x) {
a = x;
}
template <int y>
constexpr int compute() const {
if (a == 0) {
return y * y;
}
else if (a == 1) {
return 2 * y;
}
else {
return y;
}
}
private:
int a;
};
// usage
A myA(1); // private variables set only once
myA.compute<10>(); // this will check value of a
myA.compute<1>(); // this will check value of a
You could avoid the condition check if you would use e.g. a function object as a member, and set this conditioned on the value of variable a.
Anyway, I don't think that the condition check will be big performance issue. But this will depend on your application of course.
#include <functional>
#include <iostream>
class A {
public:
A(int x)
: a { x }
{
if (a == 0){
compute = [](int y){ return y*y; };
}
else if (a == 1){
compute = [](int y){ return 2*y; };
}
else{
compute = [](int y){ return y; };
}
}
std::function<int(int)> compute;
private:
int a;
};
// usage
int main()
{
A myA(1); // private variables set only once
std::cout << myA.compute(10) << std::endl;
std::cout << myA.compute(1) << std::endl;
return 0;
}
You can guarantee the conditions are evaluated at compile time by using constexpr. Note that in this case you must use C++14 for constexpr compute(...), as multiple return statements are only suppoerted in constexpr functions after C++14.
#include <iostream>
class A {
public:
constexpr A(const int x): a(x) { }
constexpr int compute(const int y) const {
// Multiple return statements inside a constexpr function
// requires C++14 or above.
if (a == 0) {
return y*y;
}
else if (a == 1) {
return 2*y;
}
else {
return y;
}
}
private:
int a;
};
int main() {
constexpr A myA(1);
constexpr int num = myA.compute(123);
std::cout << num << std::endl;
return EXIT_SUCCESS;
}
This page contains a good explanation of constexpr, as well as examples.
If parameters are runtime value, I don't see an optimal way to avoid condition or jump.
You can trade your condition by virtual call:
struct A
{
virtual ~A() = default;
virtual int compute(int) = 0;
};
struct A0 { int compute(int y) override { return y * y; } };
struct A1 { int compute(int y) override { return 2 * y; } };
struct AN { int compute(int y) override { return y; } };
std::unique_ptr<A> makeA(int a)
{
switch (a) {
case 0: return std::make_unique<A0>();
case 0: return std::make_unique<A1>();
default: return std::make_unique<AN>();
}
}
(compiler might devirtualize the call if type is known at compile time)
or "equivalent":
struct A
{
int (*f)(int); // or even std::function<int(int)> f; if you need capture.
A(int a) : f(a == 0 ? +[](int y) { return y * y; }
: a == 1 ? +[](int y) { return 2 * y; }
: +[](int y) { return y; })
{}
int compute(int y) { return f(y); }
};
(erased-type is harder for compiler to devirtualize)
I have been reading for a while, but today I can't figure someting out and find a solution.
How to return a function pointer from a function table as parameter? All similair solutions don't work for this one and end up not compiling.
I have tried a lot of methods but the compiler always returns with errors like:
function returning function is not allowed solution (when using typedef void (*func)();)
As NO parameters have to be passed into the final routine it should be possible.
My simplified example:
void PrintOne(void) { printf("One")};
void PrintTwo(void) { printf("Two")};
struct ScanListStruct
{
int Value;
void (*Routine)(void);
}
const ScanListStruct DoList[] =
{
{1, PrintOne},
{2, PrintTwo}
}
bool GetRoutine(void *Ptr, int Nr)
{
for (int x =0; x<=1; x++)
{
if (DoList[x].Value = Nr)
{
Ptr = DoList[(x)].Routine;
//((*DoList[(x)].Routine)()); // Original Working and executing version!
return true;
}
}
return false;
}
void main(void)
{
int y = 1;
void (*RoutineInMain)(); // Define
if (GetRoutine( RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
}
There a few things wrong with the code;
Syntax errors (missing ; etc.)
main must return int
GetRoutine should accept the function pointer by reference, not just a void* pointer to anything
if condition should contain an equality test, not an assignment
As follows, works as expected;
void PrintOne(void) { printf("One"); };
void PrintTwo(void) { printf("Two"); };
struct ScanListStruct
{
int Value;
void (*Routine)(void);
};
const ScanListStruct DoList[] =
{
{1, &PrintOne},
{2, &PrintTwo}
};
bool GetRoutine(void (*&Ptr)(), int Nr)
{
for (int x =0; x<=1; x++)
{
if (DoList[x].Value == Nr)
{
Ptr = *DoList[(x)].Routine;
//((*DoList[(x)].Routine)()); // Original Working and executing version!
return true;
}
}
return false;
}
int main(void)
{
int y = 1;
void (*RoutineInMain)(); // Define
if (GetRoutine( RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
}
Prints One.
You have lots of errors in your code. Like here you put the comas at the wrong place:
void PrintOne(void) { printf("One")};
void PrintTwo(void) { printf("Two")};
It should be
void PrintOne(void) { printf("One");}
void PrintTwo(void) { printf("Two");}
And here you are using the wrong operator, = instead of ==.
if (DoList[x].Value = Nr)
When the argument Ptr is a pointer, and that is passed by value, so the value assigned in the function will not be available when the function returns.
This is how your code should be:
void PrintOne(void) { printf("One"); }
void PrintTwo(void) { printf("Two"); }
typedef void(*prototype)();
struct ScanListStruct
{
int Value;
prototype Routine;
};
const ScanListStruct DoList[] =
{
{ 1, PrintOne },
{ 2, PrintTwo }
};
bool GetRoutine(prototype &Ptr, int Nr)
{
for (int x = 0; x <= 1; x++)
{
if (DoList[x].Value == Nr)
{
Ptr = DoList[(x)].Routine;
return true;
}
}
return false;
}
int main()
{
int y = 1;
prototype RoutineInMain; // Define
if (GetRoutine(RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
return 0;
}
I have a function executor which is called with function pointer and a general function origin which I wan't to pass with different parameters a and b to the executor. How can it be done?
Here is what I have tried so far:
#include <iostream>
void executor(float (*f)(float)) {
float x = 1.;
std::cout << (*f)(x) << std::endl;
}
float original(float x,float a,float b) {
return a*x + b;
}
//// Works as expected
float a = 1;
float b = 2;
float wrapped(float x) {
return original(x,a,b);
}
void call_executor_global() {
executor(wrapped);
}
//// FIRST TRY
// void call_executor_func(float a, float b) {
// float wrapped(float x) {
// return original(x,a,b);
// }
// executor(wrapped);
// }
//// SECOND TRY
// struct Wrapper {
// float a;
// float b;
// float func(float x) {
// return original(x,a,b);
// }
// };
// void call_executor_struct(float a, float b) {
// Wrapper wrapped;
// wrapped.a = a;
// wrapped.b = b;
// executor(wrapped.func);
// }
int main()
{
call_executor_global();
// call_executor_func(1,2);
// call_executor_struct(1,2);
}
You can wrap a function using several methods. It is easier if you make executor a function template.
template <typename F>
void executor(F f) {
float x = 1.;
std::cout << f(x) << std::endl;
}
Use a global function
float a = 1;
float b = 2;
float wrapped(float x) {
return original(x,a,b);
}
void call_executor_global1() {
executor(wrapped);
}
Use a lambda function
float a = 1;
float b = 2;
void call_executor_global2() {
executor([](float x) {return original(x, a, b);});
}
Use a functor
float a = 1;
float b = 2;
void call_executor_global3() {
struct wrapper
{
float operator()(float x) { return original(x, a, b); }
};
executor(wrapper());
}
See all of them working at http://ideone.com/rDKHC1.
I have written cppUnit codes in testBMath.cc. I am able to write test cases for first three functions which are add,subtract and multiply. But I am not able to write test cases for Divide and Swap.I don't know how to handle divide by zero in test cases and how to check that numbers are swapped or not in cppUnit test cases.
testMath.h
#ifndef TEST_MATH_H__
#define TEST_MATH_H__
class testMath
{
public:
int Addition(int x, int y);
int Multiply(int x, int y);
int Subtraction(int x, int y);
int Division(int x, int y);
void swap(int &x, int &y);
};
#endif
testMath.cc
#include "testMath.h"
int testMath::Addition(int x, int y)
{
return (x + y);
}
int testMath::Multiply(int x, int y)
{
return (x * y);
}
int testMath::Subtraction(int x, int y)
{
return (x - y);
}
int testMath::Division(int x, int y)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
void swap(int &a, int &b)
{
int temp;
temp = b;
b = a;
a = temp;
}
testBMath.cc
#include <iostream>
#include <string>
#include <list>
#include "cppunit/TestCase.h"
#include "cppunit/TestFixture.h"
#include "cppunit/ui/text/TextTestRunner.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/extensions/TestFactoryRegistry.h"
#include "cppunit/TestResult.h"
#include "cppunit/TestResultCollector.h"
#include "cppunit/TestRunner.h"
#include "cppunit/BriefTestProgressListener.h"
#include "cppunit/CompilerOutputter.h"
#include "netinet/in.h"
#include "testMath.h"
using namespace CppUnit;
using namespace std;
//-----------------------------------------------------------------------------
class testBMath : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(testBMath);
CPPUNIT_TEST(testAddition);
CPPUNIT_TEST(testMultiply);
CPPUNIT_TEST(testSubtraction);
CPPUNIT_TEST(testDivision);
CPPUNIT_TEST(testSwap);
CPPUNIT_TEST_SUITE_END();
public:
void setUp(void);
void tearDown(void);
protected:
void testAddition(void);
void testMultiply(void);
void testSubtraction(void);
void testDivision(void);
void testSwap(void);
private:
testMath *mTestObj;
};
//-----------------------------------------------------------------------------
void testBMath::setUp(void)
{
mTestObj = new testMath();
}
void testBMath::testAddition(void)
{
CPPUNIT_ASSERT(5 == mTestObj->Addition(2,3));
}
void testBMath::testMultiply(void)
{
CPPUNIT_ASSERT(6 == mTestObj->Multiply(2,3));
}
void testBMath::testSubtraction(void)
{
CPPUNIT_ASSERT(2 == mTestObj->Subtraction(5,3));
}
void testBMath::testDivision(void)
{
CPPUNIT_ASSERT(6 == mTestObj->Division(12,2));
//But for divide by zero how should I write
}
void testBMath::testSwap(void)
{
//How should I check for swap
}
void testBMath::tearDown(void)
{
delete mTestObj;
}
//-----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION( testBMath );
int main(int argc, char* argv[])
{
// informs test-listener about testresults
CPPUNIT_NS::TestResult testresult;
// register listener for collecting the test-results
CPPUNIT_NS::TestResultCollector collectedresults;
testresult.addListener (&collectedresults);
// register listener for per-test progress output
CPPUNIT_NS::BriefTestProgressListener progress;
testresult.addListener (&progress);
// insert test-suite at test-runner by registry
CPPUNIT_NS::TestRunner testrunner;
testrunner.addTest (CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest ());
testrunner.run(testresult);
// output results in compiler-format
CPPUNIT_NS::CompilerOutputter compileroutputter(&collectedresults, std::cerr);
compileroutputter.write ();
// return 0 if tests were successful
return collectedresults.wasSuccessful() ? 0 : 1;
}
My suggestions, change exception from const char* to something more meaningful, like std::runtime_error:
int testMath::Division(int x, int y)
{
if( b == 0 )
{
throw std::runtime_error("Division by zero condition!");
}
return (a/b);
}
Than the test's would look like:
void testBMath::testDivision(void)
{
CPPUNIT_ASSERT(6 == mTestObj->Division(12,2));
CPPUNIT_ASSERT_THROW(mTestObj->Division(12,0), std::runtime_error);
}
void testBMath::testSwap(void)
{
int x = 2;
int y = 3;
mTestObj->swap(x, y);
CPPUNIT_ASSERT(x == 3 && y == 2);
}