I implemented the lambda-calculus in C++, but now I don't know how to get out of it. I would like to test if my functions return the right thing, but I cant compare the result, since it is a funtion. Does anyone have an idea how I could test my code?
#include <functional>
class function :
public std::function<function (function)> {
public: using type =
std::function<function (function)>;
public: using type::function;
};
function True = [](function x) {
return [&](function y) {
return x;
};
};
function False = [](function x) {
return [&](function y) {
return y;
};
};
function If = [](function x) {
return [&](function y) {
return [&](function z) {
return x(y)(z);
};
};
};
function And = [](function x) {
return [&](function y) {
return x(y)(x);
};
};
function Or = [](function x) {
return [&](function y) {
return x(x)(y);
};
};
// ...
int main()
{
// ?
}
I solved my problem with the following test code.
#include <cassert>
#include <exception>
template <typename E, typename F>
bool throws(F f)
try {
f();
return false;
}
catch (E const &) {
return true;
}
auto main() -> int
{
function Null;
assert(throws<std::bad_function_call>([&] { True(Null)(True)(True); }));
assert(throws<std::bad_function_call>([&] { False(True)(Null)(True); }));
}
The test for False worked, but the test for True didn't. The first assert did not pass and I don't know why. When I capture x by value instead of by reference ([&] -> [=]) everything works.
New code for True:
function True = [](function x) {
return [=](function y) {
return x;
};
};
Does anyone know why it doesn't work if I capture by reference?
My code looks now like this (I just replaced all [&] by [=] and used private inheritance):
class function :
private std::function<function (function)> {
public: using type =
std::function<function (function)>;
public: using type::function;
public: using type::operator();
public: using type::operator bool;
};
function True = [](function t) {
return [=](function f) {
return t;
};
};
function False = [](function t) {
return [=](function f) {
return f;
};
};
function If = [](function x) {
return [=](function t) {
return [=](function f) {
return x(t)(f);
};
};
};
function And = [](function x) {
return [=](function y) {
return x(y)(x);
};
};
function Or = [](function x) {
return [=](function y) {
return x(x)(y);
};
};
And the tests look like this:
auto main() -> int
{
function Null;
assert( True(True)(Null));
assert(!True(Null)(True));
assert( False(Null)(True));
assert(!False(True)(Null));
assert( If(True )(True)(Null));
assert(!If(True )(Null)(True));
assert( If(False)(Null)(True));
assert(!If(False)(True)(Null));
assert(And(False)(False) (Null)(True));
assert(And(False)(True ) (Null)(True));
assert(And(True )(False) (Null)(True));
assert(And(True )(True ) (True)(Null));
assert(Or(False)(False) (Null)(True));
assert(Or(False)(True ) (True)(Null));
assert(Or(True )(False) (True)(Null));
assert(Or(True )(True ) (True)(Null));
}
Related
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
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)
So i need to make a new repo in my app who will throw exceptions with a given probability in his constructor.
This is what i have in my repo.h file:
Repository class is the main repo class which uses memory, RepositoryFile is using a txt file and then i want to make RepositoryM the repo who will throw exceptions. But i dont know how can i do this. RepositoryM should also work like a normal repository if he doesnt throw an exception.
#pragma once
#include "Domain.h"
#include <string>
#include <vector>
#include <algorithm>
#include <exception>
using namespace std;
class Repository
{
private:
vector<Activitate> all;
public:
Repository() = default;
Repository(const Activitate& ot) = delete;
virtual ~Repository()=default;
virtual void store(const Activitate& a) {
auto found = std::find_if(all.begin(), all.end(), [a](const Activitate& aa) {
return aa.getDescriere() == a.getDescriere() && aa.getTitlu() == a.getTitlu();
});
if (found != all.end()) {
throw ActivitateException{ "Activitate existenta !" };
}
all.push_back(a);
}
const Activitate& find(std::string titlu, std::string descriere) {
auto found = std::find_if(all.begin(), all.end(), [&](const Activitate& aa) {
return aa.getTitlu() == titlu && aa.getDescriere() == descriere;
});
if (found == all.end()) {
throw ActivitateException{ "Activitate inexistenta !" };
}
return *found;
}
const vector<Activitate>& getAll() const {
return all;
}
virtual void clearAll() {
all.clear();
}
virtual int sizeAll() const {
int i = 0;
for (const auto& activitate : getAll()) {
i++;
}
return i;
}
virtual void stergere(const Activitate& a) {
auto found = std::find_if(all.begin(), all.end(), [a](const Activitate& aa) {
return aa.getTitlu() == a.getTitlu() && aa.getDescriere() == a.getDescriere();
});
if (found == all.end()) {
throw ActivitateException{ "Activitate inexistenta !" };
}
auto rez = all.erase(found);
}
virtual void modifica(const Activitate& a, const Activitate& b) {
auto found = std::find_if(all.begin(), all.end(), [a](const Activitate& aa) {
return aa.getTitlu() == a.getTitlu() && aa.getTip() == a.getTip();
});
if (found == all.end()) {
throw ActivitateException{ "Activitate inexistenta !" };
}
auto rez = all.erase(found);
all.push_back(b);
}
};
class RepositoryFile : public Repository {
private:
string fName;
void loadActivitateFromFile();
void writeActivitateToFile();
public:
RepositoryFile(std::string fName) :Repository(), fName{ fName } {
loadActivitateFromFile();
}
void store(const Activitate& act) override {
Repository::store(act);
writeActivitateToFile();
}
void stergere(const Activitate& act) override {
Repository::stergere(act);
writeActivitateToFile();
}
void modifica(const Activitate& a, const Activitate& b) override {
Repository::modifica(a,b);
writeActivitateToFile();
}
void clearAll() override {
Repository::clearAll();
writeActivitateToFile();
}
};
class RepositoryM: public Repository{
private:
int prob;
public:
void store(const Activitate& act) override {
Repository::store(act);
}
void stergere(const Activitate& act) override {
Repository::stergere(act);
}
void modifica(const Activitate& a, const Activitate& b) override {
Repository::modifica(a, b);
}
void clearAll() override {
Repository::clearAll();
}
RepositoryM(int prob) :Repository(), prob{ prob } {
}
};
void testeRepo();
You can use the random library. So the contructor of RepositoryM would look like the following
RepositoryM(int prob) :Repository(), prob{ prob } {
if (((double) rand() / RAND_MAX) < ((double) prob / 100))
throw "some error";
std::cout << "Running normally" << std::endl;
}
Don't forget to include <random> and <ctime>
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.