Mutable vs Lazy Evaluation - c++

Recently I was reading this faq on const-correctness. Now I came across the following situation where I dont know what to make const or mutable.
Assume the simple example:
class Averager {
public:
Averager() : sum(0),isUptoDate(false),N(0){}
void add(double x){
sum+=x;
N+=1;
isUptoDate = false;
}
double getAverage() const {
if (!isUptoDate){updateAverage();}
return average;
}
private:
void updateAverage(){
if(N>0){average = sum / N;}
else {average = 0;}
isUptoDate = true;
}
double sum;
mutable bool isUptoDate;
int N;
double average;
};
In the real case, updateAverage() is an expensive calculation, thus I want to avoid updating each time a value is added. Also, getAverage() might be called several times, before a new value is added, thus I want to update only if really necessary. On the other hand, it should not be the responsibility of the user of the class to call updateAverage(), thus I used the flag to know whether an update has to be made or not.
As I understood, getAverage() should clearly be a const method while isUptoDate can be mutable (its not part of the logical state but just a private implementation detail). However, updateAverage() is definitely not const and I cannot call it from within a const method.
What is wrong with my approach?

It looks fine to me, you just need to make your average also mutable, because it'll be lazily computed by getAverage. updateAverage should also be const, because it will be called by getAverage. Since updateAverage is private, its own existence is an implementation detail. It's called only once, you could as well inline it into getAverage:
double getAverage() const {
if (!isUptoDate){
if(N>0){average = sum / N;}
else {average = 0;}
isUptoDate = true;
}
return average;
}
Indeed, I really suggest you inline it, because it makes no sense to have it in the header file (you have to recompile all the users if you change its signature or its const-ness). If it's not just 3 lines in the real case, you can have it as a lambda, if you use C++11:
double getAverage() const {
auto updateAverage=[&]{
if(N>0){average = sum / N;}
else {average = 0;}
isUptoDate = true;
};
if (!isUptoDate){ updateAverage(); }
return average;
}

Related

How to program a function whose return value is depending on the flag without using "if"?

I want to make a class function like the conceptual code below.
double function(){
if(flag==true){
"some process and return "
}
else{
"another process and return"
}
}
where flag is the boolean member of the class.
I want to make this function without using if because I use this function many times.
The points are
I want to use the same function with the two cases of the process.
I want to avoid re-evaluation of a flag that doesn't change its value for some period.
If you want to call one of two different member functions depending on the value of a bool without using an if or something else that might lead to branching, you could create a table containing two function pointers and use that for lookup by using the bool for indexing. If you only want to do this lookup when the value of the flag changes, you could store a pointer to the active function and only do the lookup when flag is set.
Example where the member functions are also taking an argument:
#include <iostream>
class foo {
public:
using func_t = double(foo::*)(double); // the type of the member functions
double some(double x) { return x * 3.14159; }
double another(double x) { return x * 3.14159 * 3.14159; }
double function(double x) {
return (this->*active)(x); // "active" only changes when "flag" is set
}
void set(bool x) {
flag = x;
// lookup without "if" to set the active function:
active = funcs[flag];
}
private:
// a static table of the functions to be called - only initialized once
static constexpr func_t funcs[]{&foo::some, &foo::another};
bool flag = false;
func_t active = &foo::some; // the active function
};
int main() {
foo x;
x.set(false);
std::cout << x.function(2.) << '\n';
x.set(true);
std::cout << x.function(3.) << '\n';
}
Output
6.28318
29.6088
Class function, flag, and two different behaviors? You probably should make two derived classes, drop the flag, and use a virtual function instead.
You can just cast the boolean into an int
int test(bool flag)
{
return static_cast<int>(flag);
}
int not_test(bool flag)
{
return static_cast<int>(!flag);
}
Remark: By the time this answer was posted, the question was completely different.

How do I re-assign a function name in C++

I have a problem in C++ that is similar to this example problem. In this case I have two member-functions that have an identical interface. Based on the information in a string passed to the super function, I would like to assign one of the two member functions to the variable class_func. Is there a way to do this?
// test.hpp
class TestClass
{
public:
double master_function(double a, double b, std::string func_name);
private:
double add(double a, double b);
double subtract(double a, double b);
};
// test.cpp
double TestClass::master_function(double a, double b, std::string func_name)
{
if (func_name == std::string("Add") const auto& class_func = add;
else const auto& class_func = subtract;
return class_func(a, b);
}
// =========================================================================
double TestClass::add(double a, double b)
{
return a + b;
}
// =========================================================================
double TestClass::subtract(double a, double b)
{
return a - b;
}
In other words, I am trying to assign the member-function add or subtract to the name class_func, so the code underneath the if statement in master_function can be uniform regardless of which function the user wants to use. In the form shown below I get the error Reference to non-static member function must be called out, but I am not totally sure what this means or how to fix it. In addition, I am using a C++17 compiler, so if there is a modern approach that works best with C++17 I would be interested in learning it.
The term you are looking for is member function pointer, but we can do without explicitly specifying that type. The problem with your code is not only in the way you try to refer to a member function (that would be &TestClass::add), but also that you create those aliases in a nested scope (under if/else), meaning they won't be visible in the return statement.
The simplest change is this:
auto class_func = &TestClass::add; // pick one default
if (func_name == "Subtract")
{
class_func = &TestClass::subtract;
}
else
{
assert(func_name == "Add"); // optional
}
return class_func(a, b);
This works because the add and subtract functions have the exact same type:
double (TestClass::*)(double a, double b)
But yeah, why are those functions not static? They do not work with a class' instance. Make them static and the above will still work, just note that the type of class_fun will be a simple function pointer:
double (*)(double a, double b)
Now that you know the types, you could change this in a way that does not privilege one function before the other in the code:
decltype(&TestClass::add) class_func = nullptr;
if (func_name == "Add")
{
class_func = &TestClass::add;
}
else if (func_name == "Subtract")
{
class_func = &TestClass::subtract;
}
assert(class_func != nullptr);
return class_func(a, b);
As mentioned in the comments, as that if-else chain starts to get longer, it makes more and more sense to use a (hash)map between strings and function pointers.

Mutators (set-functions) with return value?

Im studying programming and I just started learning about set and get functions.
My questions is if it is common practise to use set-functions with a return value?
Like when the set-function performs validation i would like it to return true if the incoming value passes the validation.
Googled it and looked throug my course material and found nothing, only void set-functions everywhere!! :)
Thx
In some cases you may want to return the reference to *this from setter methods to implement fluent interface. A simple example:
class C {
int x,y;
public:
C& setX(int value) { x = value; return *this; }
C& setY(int value) { y = value; return *this; }
};
such class may be then used in the following way:
C c;
c.setX(1).setY(2);
The core motivation for getter/setter is value validation / sanity check values so returning a bool is a common way to make known if operation occurred successfully:
bool Class::setSomething(int a)
{
if (is_ok(a))
{
// set...
return true;
}
return false;
}
This is
quick/easy to implement
has smaller footprint than exception handling (although this is negligible these days)
but
it can't pass back any extra information to the caller (why did it break?)
is easier to ignore compared to exceptions
Depending on what the setter is doing.
My set functions which only assign values to class members are void
void Class::setParameter(Parameter param)
{
m_parameter = param;
}
if the setter is doing more than this, I can envisage returning a boolean.

How do I create a function with multiple identifiers?

I want to make a function, and in different contexts it is better called by different names.
class box(){
private:
float posX;
float size = 10;
public:
float speedX;
float left(){ return posX; } //Any way to combine these?
float posX(){ return posX; } //Any way to combine these?
float right(){ return posX + size; }
};
box a;
box b;
bool checkCollide(){
if(a.right() < b.left()){ return 0; } //Not colliding
if(b.right() < a.left()){ return 0; } //Not colliding
return 1; //Colliding
} //Comparing right and left makes more sense than anything else
void physics(){
a.posX() += a.speedX;
b.posX() += b.speedX;
//Adding speed to position makes more sense than
//adding speed to "left"
}
//Loop physics X times per second, and do something if there's a collision
or, is there a better way to do this? Can I make the left/right member automatically update any time the position or size changes, instead of recalculating for every call?
If you are really obliged to do this, then just make the one function call the other:
// the function that does the hard job
float foo(float a, float b)
{
// some heavy and complicated code
// ...
// some more black magic, etc.
// finally:
return sqrt(a * a + b * b);
}
// the function that pretends to do the hard job
float bar(float a, float b)
{
return foo(a, b);
}
But you better not do this, it's quite bad style. Different names => different tasks. Same task => same name. Don't hurt the intuition of your fellows... ;-)
Yes - Not write two functions that at the start do the same thing. I just hope that they do not diverge. Then you have problems!
If you're on C++11, or when using Boost, you can bind the left() function to an std::function variable. With C++11:
class box {
// ...
public:
// ...
float left() { return posX; }
const std::function<float()> posx = std::bind(&box::left, this);
The const is needed, otherwise posx could be changed at runtime to point to a different function.
If you're not using a C++11 compiler but use Boost instead, then it's not that expressive, since you have to initialize posx in the ctor:
class box {
// ...
public:
box() : posx = boost::bind(&box::left, this);
// ...
float left() { return posX; }
const boost::function<float()> posx;
In both cases, you can now do:
box b;
b.left();
b.posx();
This method doesn't really have any advantages I can think of compared to having a posx() function and calling left() in it. But it's possible and so deserves a mention.
But I agree with what H2CO3 said: don't have two names for the same function. It's confusing.

optimize output value using a class and public member

Suppose you have a function, and you call it a lot of times, every time the function return a big object. I've optimized the problem using a functor that return void, and store the returning value in a public member:
#include <vector>
const int N = 100;
std::vector<double> fun(const std::vector<double> & v, const int n)
{
std::vector<double> output = v;
output[n] *= output[n];
return output;
}
class F
{
public:
F() : output(N) {};
std::vector<double> output;
void operator()(const std::vector<double> & v, const int n)
{
output = v;
output[n] *= n;
}
};
int main()
{
std::vector<double> start(N,10.);
std::vector<double> end(N);
double a;
// first solution
for (unsigned long int i = 0; i != 10000000; ++i)
a = fun(start, 2)[3];
// second solution
F f;
for (unsigned long int i = 0; i != 10000000; ++i)
{
f(start, 2);
a = f.output[3];
}
}
Yes, I can use inline or optimize in an other way this problem, but here I want to stress on this problem: with the functor I declare and construct the output variable output only one time, using the function I do that every time it is called. The second solution is two time faster than the first with g++ -O1 or g++ -O2. What do you think about it, is it an ugly optimization?
Edit:
to clarify my aim. I have to evaluate the function >10M times, but I need the output only few random times. It's important that the input is not changed, in fact I declared it as a const reference. In this example the input is always the same, but in real world the input change and it is function of the previous output of the function.
More common scenario is to create object with reserved large enough size outside the function and pass large object to the function by pointer or by reference. You could reuse this object on several calls to your function. Thus you could reduce continual memory allocation.
In both cases you are allocating new vector many many times.
What you should do is to pass both input and output objects to your class/function:
void fun(const std::vector<double> & in, const int n, std::vector<double> & out)
{
out[n] *= in[n];
}
this way you separate your logic from the algorithm. You'll have to create a new std::vector once and pass it to the function as many time as you want. Notice that there's unnecessary no copy/allocation made.
p.s. it's been awhile since I did c++. It may not compile right away.
It's not an ugly optimization. It's actually a fairly decent one.
I would, however, hide output and make an operator[] member to access its members. Why? Because you just might be able to perform a lazy evaluation optimization by moving all the math to that function, thus only doing that math when the client requests that value. Until the user asks for it, why do it if you don't need to?
Edit:
Just checked the standard. Behavior of the assignment operator is based on insert(). Notes for that function state that an allocation occurs if new size exceeds current capacity. Of course this does not seem to explicitly disallow an implementation from reallocating even if otherwise...I'm pretty sure you'll find none that do and I'm sure the standard says something about it somewhere else. Thus you've improved speed by removing allocation calls.
You should still hide the internal vector. You'll have more chance to change implementation if you use encapsulation. You could also return a reference (maybe const) to the vector from the function and retain the original syntax.
I played with this a bit, and came up with the code below. I keep thinking there's a better way to do this, but it's escaping me for now.
The key differences:
I'm allergic to public member variables, so I made output private, and put getters around it.
Having the operator return void isn't necessary for the optimization, so I have it return the value as a const reference so we can preserve return value semantics.
I took a stab at generalizing the approach into a templated base class, so you can then define derived classes for a particular return type, and not re-define the plumbing. This assumes the object you want to create takes a one-arg constructor, and the function you want to call takes in one additional argument. I think you'd have to define other templates if this varies.
Enjoy...
#include <vector>
template<typename T, typename ConstructArg, typename FuncArg>
class ReturnT
{
public:
ReturnT(ConstructArg arg): output(arg){}
virtual ~ReturnT() {}
const T& operator()(const T& in, FuncArg arg)
{
output = in;
this->doOp(arg);
return this->getOutput();
}
const T& getOutput() const {return output;}
protected:
T& getOutput() {return output;}
private:
virtual void doOp(FuncArg arg) = 0;
T output;
};
class F : public ReturnT<std::vector<double>, std::size_t, const int>
{
public:
F(std::size_t size) : ReturnT<std::vector<double>, std::size_t, const int>(size) {}
private:
virtual void doOp(const int n)
{
this->getOutput()[n] *= n;
}
};
int main()
{
const int N = 100;
std::vector<double> start(N,10.);
double a;
// second solution
F f(N);
for (unsigned long int i = 0; i != 10000000; ++i)
{
a = f(start, 2)[3];
}
}
It seems quite strange(I mean the need for optimization at all) - I think that a decent compiler should perform return value optimization in such cases. Maybe all you need is to enable it.