Call list of methods in derived class - c++

I am developing a test-framework. There are a number of test-suites, each is a class with a set of member functions for each individual test.
I would like to find a way to dynamically iterate through all of the tests in a class.
The idealised setup might look something like this:
class A : public Test
{
public:
A() {
addTest(a);
addTest(b);
addTest(c);
}
void a() { cout << "A::a" << endl; }
void b() { cout << "A::b" << endl; }
void c() { cout << "A::c" << endl; }
};
The addTest() method will add its parameter to a list; this list is iterated through at a later point and each method is run.
Is there any way to achieve this? The closest we have come up with so far is this:
class Test
{
public:
template <typename T>
struct UnitTest
{
typedef void (T::*P)();
P f;
UnitTest(P p) : f(p) {}
};
// (this struct simplified: we also include a name and description)
virtual void run(int testId) = 0;
};
class A : public Test
{
public:
A() {
mTests.push_back(UnitTest<A>(&A::a));
mTests.push_back(UnitTest<A>(&A::b));
mTests.push_back(UnitTest<A>(&A::c));
}
void a() { cout << "a" << endl; }
void b() { cout << "b" << endl; }
void c() { cout << "c" << endl; }
// not ideal - this code has to be repeated in every test-suite
void run(int testId)
{
(this->*(mTests[testId].f))();
}
vector<UnitTest<A>> mTests;
};
To invoke one test per-iteration of the main run-loop:
a->run(mTestId++);
This is not ideal because every test-suite (class) has to repeat the run() code and have its own mTests member.
Is there a way to get closer to the ideal?

Make each test a functor or function object. Create a container of pointers to the tests and then iterate over the container:
struct Test_Base_Class
{
virtual bool Execute(void) = 0;
};
typedef std::vector<Test_Base_Class *> Container_Of_Tests;
struct Test_Engine
{
Container_Of_Tests tests_to_run;
void Add_Test(Test_Base_Class * p_new_test)
{
tests_to_run.push_back(p_new_test);
}
void Run_Tests(void)
{
Container_Of_Tests::iterator iter;
for (iter = tests_to_run.begin();
iter != tests_to_run.end();
++iter)
{
(*iter)->Execute(); // Invoke the Execute method on a test.
}
return;
}
}
This is the foundation. I am currently using this pattern but have expanded to include a Resume() method and status reporting.

Related

C++: implement a bool template parameter in virtual function

A performance bottleneck of my program is frequent calls to functions like following update functions.
Given that flag parameter is always a bool literal, I want to "unroll" the update function to two versions, one with flag=true and one with flag=false, to avoid branch prediction failure.
for normal functions, a bool template parameter can solve this problem easily.
However, template cannot be applied to virtual functions.
I can create two virtual functions manually, but then I have to copy the long code part. It makes futher development harder.
Is there anyway allowing me to write two versions in one function, controlled by a compiling-time constant flag?
#include <iostream>
#include <random>
using std::cout;
using std::endl;
struct Base
{
virtual void update(bool flag) = 0;
};
struct Derived1 : public Base
{
void update(bool flag)
{
if (flag)
{
// some computations
cout << "Derived1 flag=true" << endl;
}
else
{
// some computations
cout << "Derived1 flag=false" << endl;
}
// long code containing several flag-conditioned blocks like the block above
cout << "Derived1" << endl;
}
};
struct Derived2 : public Base
{
void update(bool flag)
{
if (flag)
{
// some computations
cout << "Derived2 flag=true" << endl;
}
else
{
// some computations
cout << "Derived2 flag=false" << endl;
}
// long code containing several flag-conditioned blocks like the block above
cout << "Derived2" << endl;
}
};
int main()
{
Base *p;
srand(time(nullptr));
if (rand() % 2 == 1)
{
p = new Derived1();
}
else
{
p = new Derived2();
}
p->update(false);
p->update(true);
}
Unfortunately, there is no such thing as virtual templates. What can be done however is to create several virtual functions taking an integral (boolean in this particular case) constant, if the flag is really a compile time literal:
#include <iostream>
#include <random>
#include <type_traits>
#include <memory>
using std::cout;
struct Base
{
virtual void updateSeparate(std::true_type) = 0;
virtual void updateSeparate(std::false_type) = 0;
};
struct Derived1 : public Base
{
void updateSeparate(std::true_type)
{
cout << "Derived1 flag=true\n";
updateCommonImpl();
}
void updateSeparate(std::false_type)
{
cout << "Derived1 flag=false\n";
updateCommonImpl();
}
private:
void updateCommonImpl() //or just a static function inside implementation file if members are not used
{
cout << "Derived1\n";
}
};
struct Derived2 : public Base
{
void updateSeparate(std::true_type)
{
cout << "Derived2 flag=true\n";
updateCommonImpl();
}
void updateSeparate(std::false_type)
{
cout << "Derived2 flag=false\n";
updateCommonImpl();
}
private:
void updateCommonImpl() //or just a static function inside implementation file if members are not used
{
cout << "Derived2\n";
}
};
int main()
{
std::unique_ptr<Base> p;
srand(time(nullptr));
if (rand() % 2 == 1)
{
p = std::make_unique<Derived1>();
}
else
{
p = std::make_unique<Derived2>();
}
p->updateSeparate(std::bool_constant<false>{});
p->updateSeparate(std::bool_constant<true>{});
}
DEMO
However, I cannot tell if that will help or maybe hinder the performance even more by making the vtable lookup time even longer, you have to experiment with that by yourself I'm afraid.
I tried to implement a CRTP pattern with constexpr template parameter, please take a look
template<typename T>
struct Base {
template<bool flag>
int update() {
return static_cast<T*>(this)->template updateImpl<flag>();
}
};
struct Derived1 : public Base<Derived1> {
template<bool flag>
constexpr int updateImpl() {
if constexpr (flag) {
return 1;
} else {
return 2;
}
}
};
struct Derived2 : public Base<Derived2> {
template<bool flag>
constexpr int updateImpl() {
return 3;
}
};
int main() {
auto obj1 = new Derived1();
std::cout << obj1->update<true>(); // 1
std::cout << obj1->update<false>(); // 2
auto obj2 = new Derived2();
std::cout << obj2->update<true>(); // 3
std::cout << obj2->update<false>(); // 3
}

About std::function usage and if-else problem

as the below code, I don't want so many "if else"
class A
{
public:
void f0()
{
cout << "f0" << endl;
}
void f1()
{
cout << "f1" << endl;
}
void f2()
{
cout << "f2" << endl;
}
//..... more functions fn()...
};
class B
{
public:
void f(int n)
{
//vector< function<void()> > f_v {obj_a.f0, obj_a.f1, obj_a.f2}; //this usage is not correct
if (n == 0)
obj_a.f0();
else if (n == 1)
obj_a.f1();
else if (n == 2)
obj_a.f2();
//.....more else if here
}
private:
A obj_a;
};
I want to create a vector and use std::function to avoid using so many if-else , like vector< function<void()> > f_v {obj_a.f0, obj_a.f1, obj_a.f2}; but it doesn't work, maybe the usage of std::function is not very correct. How should I do? Or is there any other good way to solve the problem of if else, I think use so many switch-case is also not very elegant :)
update:
Some answers have already solve my problem about the usage of std::function in my earlier code;
More generally, considering the below code, if the member functons A::f1(), A::f2().... have different return types, but still have some connection that they derived from a same base class , what's the good way to implement the logic of if else in B::f()?
class Base
{
public:
virtual ~Base()=default;
};
class D1 : public Base
{
public:
};
class D2 : public Base
{
public:
};
class D3 : public Base
{
public:
};
// ....maybe more class derived form Base
class A
{
public:
D1* f0()
{
cout << "f0" << endl;
return &d1;
}
D2* f1()
{
cout << "f1" << endl;
return &d2;
}
D3* f2()
{
cout << "f2" << endl;
return &d3;
}
//more fn()....
private:
D1 d1;
D2 d2;
D3 d3;
//.....
};
class B
{
public:
void f(int n)
{
if (n == 0)
obj_a.f0();
else if (n == 1)
obj_a.f1();
else if (n == 2)
obj_a.f2();
//.....more else if here
}
private:
A obj_a;
};
You can use std::function with a lambda wrapper,
vector<function<void()>> f_v {[this]() { obj_a.f0(); },
[this]() { obj_a.f1(); },
[this]() { obj_a.f2(); }};
f_v[n]();
or use pointer-to-members directly,
vector<void (A::*)()> f_v { &A::f0, &A::f1, &A::f2 };
(obj_a.*f_v[n])();
If you are aiming at speed and you know the number of methods, avoid using std::vector for the extra indirection. Use std::array as it will hit cache with the current object.
For this simple case, you don't necessarily need to use std::function, which is a very heavy object to call. You can use pointers to members like this:
#include <iostream>
#include <array>
using namespace std;
class A
{
public:
void f0()
{
cout << "f0" << endl;
}
void f1()
{
cout << "f1" << endl;
}
void f2()
{
cout << "f2" << endl;
}
//.....
};
class B
{
public:
B() {
fn[0] = &A::f0;
fn[1] = &A::f1;
fn[2] = &A::f2;
}
void f(int n)
{
((obj_a).*(fn[n]))();
}
private:
using Fn = void (A::*)();
std::array<Fn,3> fn;
A obj_a;
};
Code: https://godbolt.org/z/z4KqKvn99
Your approach seems correct. You just need to std::bind those member functions like
class B{
std::vector <std::function <void()>> m_vec_functs;
...
B(const A& a)
{
m_vec_functs.push_back(std::bind(&A::f0, a));
m_vec_functs.push_back(std::bind(&A::f1, a));
}
void f(unsigned int n)
{
m_vec_functs[n];
}
...
};
Then you can access each individual function by its index, knowing their order.

static polymorphism and template Containers

I'm trying to use the static polymorphism and template to create a container that can hold more the one type, from what I know about template it can't be done, but I'm hoping that I'm wrong and there is a way.
I have the following classes:
template<class Derived>
class base
{
public:
base(string);
void clean()
{
cout << "I'm cleannig \n";
}
void process()
{
static_cast<Derived*>(this)->setup();
static_cast<Derived*>(this)->run();
static_cast<Derived*>(this)->cleanup();
}
string name;
};
template<class Derived>
base<Derived>::base(string y):name(y)
{
}
class derived : public base<derived>
{
friend class base<derived>;
void setup() {cout << "derived setup \n"; }
void run() { cout << "derived run \n"; }
void cleanup() { cout << "derived cleanup \n"; }
};
class derived1 : public base<derived1>
{
friend class base<derived1>;
void setup() {cout << "derived1 setup \n"; }
void run() { cout << "derived1 run \n"; }
void cleanup() { cout << "derived1 cleanup \n"; }
};
and I wont to create a container that can hold them, I tried this code -
template <class T>
class Y{
public:
std::vector<base<T>> m_vec;
};
template <typename T>
class D:public Y<T>
{
public:
friend class Y<T>;
void print()
{
for(auto& e: Y<T>::m_vec)
{
e.process();
}
}
};
int main()
{
base<derived>* b = new base<derived>;
base<derived1>* c = new base<derived1>;
D<derived> y;
y.m_vec.push_back(b);
y.m_vec.push_back(c);
y.print();
}
but its not working
i tryed to do this:
y.m_vec.push_back(static_cast<base<derived>>(c));
and I'm getting this error:
error: no matching function for call to ‘std::vector, std::allocator > >::push_back(base*&)’
y.m_vec.push_back(b);
after some testing and digging the answer is that there isn't a way to do it. but you can use std::any like #formerlyknownas_463035818 suggested
declare the std::vector as :
`std::vector<std::any> m_vec;`
Instead of
std::vector<base<T>> m_vec;
and use the boost demangle function to get the type -
std::string name(boost::core::demangle(e.type().name()));
and then use some kind of factory functio to any_cast to the type you need
if(!name.compare("base<derived1>*") )
{
try {
auto* r = any_cast<base<derived1>*>(e);
r->process();
}
catch(const std::bad_any_cast& e) {
std::cout << e.what() << '\n';
}
}
else
{
try {
auto *r = any_cast<base<derived> *>(e);
r->process();
}
catch(const std::bad_any_cast& e) {
std::cout << e.what() << '\n';
}
}
or instead of using the demangle name and use string compare you can use the type() function of the class any and compare is to the typeid like this:
if(e.type()==typeid(base<derived1>*))

Strange way to call a method from an instance object...

digging some codes, I found a curiously manner to call a method from an instance object which I will show in the example code bellow:
class Example{
public:
void Print(){ std::cout << "Hello World" << std::endl;}
};
int main(){
Example ex;
ex.Example::Print(); // Why use this notation instead of just ex.Print();
return 0;
}
There is any behaviour difference between ex.Example::Print() and the standard way ex.Print()? Why the author' code used the former instead of the latter?
Thanks in advance
The difference is that ex.Example::Print() specifies that you want the version of Print() defined in the class Example. In this particular example, there's no difference. However, consider the following:
#include <iostream>
class One {
int i;
public:
One(int ii) : i(ii) {}
virtual void print() { std::cout << i << std::endl; }
};
class Two : public One {
int j;
public:
Two(int ii, int jj) : One(ii), j(jj) {}
void print() override {
One::print();
std::cout << j << std::endl;
}
};
class Three : public Two {
int k;
public:
Three(int ii, int jj, int kk) : Two(ii, jj), k(kk) {}
void print() override {
Two::print();
std::cout << k << std::endl;
}
};
int main() {
Three four(1, 2, 3);
four.print();
std::cout << std::endl;
four.One::print();
std::cout << std::endl;
four.Two::print();
std::cout << std::endl;
four.Three::print();
std::cout << std::endl;
}
The output will be:
1
2
3
1
1
2
1
2
3
ex.Example::Print(); // Why use this notation instead of just ex.Print();
Given the posted code, that is the same as:
ex.Print();
It will make a difference only if name hiding comes into play and you want to be explicit about calling a particular version of the function.
Ex:
struct Foo
{
void Print() const { std::cout << "Came to Foo::Print()\n"; }
};
struct Bar : Foo
{
void Print() const { std::cout << "Came to Bar::Print()\n"; }
};
int main()
{
Bar b;
b.Print(); // Calls Bar::Print()
b.Foo::Print(); // Calls Foo::Print()
}
That's just the mechanics of how things work. As a design choice, it will be better to use virtual functions:
struct Foo
{
virtual void Print() const { std::cout << "Came to Foo::Print()\n"; }
};
struct Bar : Foo
{
virtual void Print() const { std::cout << "Came to Bar::Print()\n"; }
};
No difference between calling ex.Example::Print() and ex.Print() in this example.
The only use/benefit of this invocation I can think of is with inheritance; You can explicitly call over-ridden method in parent class using this syntax from an instance of derived class.

RAII objects in a singleton container?

So, I was wondering how to create some kind of a code audit in C++ using a tracking mechanism of sorts.
Consider the following classes, where two separate mirrors, A and B, provide messages to a listener.
class MirrorA
{
void one(int a) { m_mirrrorListener.three(a); }
};
class MirrorB
{
void two(int b) { m_mirrrorListener.three(b); }
};
class MirrorListener
{
void three(int c) { std::cout << c << std::endl; }
};
Now, let's say that, for some reason, three needs to know if it was triggered by one() or two().
We can pass along a value like so:
enum mirrorSource_t
{
FROM_ONE = 1,
FROM_TWO = 2
}
class MirrorA
{
void one(int a) { m_mirrrorListener.three(a, FROM_ONE); }
};
class MirrorB
{
void two(int b) { m_mirrrorListener.three(b, FROM_TWO); }
};
class MirrorListener
{
void three(int c, mirrorSource_t source) { std::cout << c << " From " << source << std::endl; }
};
But then we have to update the signature of three and its invocation whenever it needs new information.
So, what if we had a singleton message tracker (referenced as m_mirrorMessageTracker in other classes) that could track an arbitrary number of messages?
enum mirrorSource_t
{
FROM_ONE = 1,
FROM_TWO = 2
}
class MirrorMessage
{
public:
MirrorMessage(mirrrorSource_t t) : source(t) {}
get() { return source; }
private:
mirrorSource_t source;
};
class MirrorMessageTracker {
public:
MirrorMessage& MirrorMessageTracker::trackEvent(mirrorSource_t value)
{
trackedMessages.push_back(MirrorMessage(value));
return trackedMessages.back();
}
MirrorMessage& MirrorMesssageTracker::getCurrentEvent()
{
return trackedMessages.back();
}
static MirrorMessageTracker& getInstance()
{
if(!m_Tracker)
{
m_pTracker = new MirrorMessageTracker();
}
return *m_pTracker;
}
private:
MirrorMessageTracker() { }; //
static MirrorMessageTracker* m_pTracker;
std::vector<MirrorMessage> trackedMessages; // assumption is that tracked messages are
// single-threaded and unwind in a LIFO manner.
};
class MirrorA
{
void one(int a)
{
MirrorMessage createdMessage = m_MirrorMessageTracker.trackMessage(FROM_ONE);
m_mirrrorListener.three(a);
}
};
class MirrorB
{
void two(int b)
{
MirrorMessage createdMessage = m_MirrorMessageTracker.trackMessage(FROM_TWO);
m_mirrrorListener.three(b);
}
};
class MirrorListener
{
void three(int c)
{
MirrorMessage& message = m_MirrorMessageTracker.getCurrentMessage();
if (message.get() == FROM_ONE)
{
std::cout << c << std::endl;
}
else if (message.get() == FROM_TWO)
{
std::cout << c << c << std::endl;
}
else
{
std::cout << c << c << c << std::endl;
}
}
};
I would like for the tracked message to be removed from the tracker after createdMessage goes out of scope in one and two. Can this be done with a particular type of boost smart pointer? Something like:
std::vector<boost::shared_ptr<MirrorMessage> > trackedMessages;
vector::push_back would create a copy of the message and place it into the vector so I'm not sure if it's possible with a shared pointer, though.
The more common pattern to create singletons actually is
static MirrorMessageTracker& getInstance() {
static MirrorMessageTracker theMirrorMesageTracker;
return theMirrorMesageTracker;
}
Also you should consider to forbid copying and assignment for your MirrorMessageTracker class, by making these operations private:
private:
MirrorMessageTracker() { };
MirrorMessageTracker(const MirrorMessageTracker&); // <<<
MirrorMessageTracker& operator=(const MirrorMessageTracker&); // <<<