simple C++ basic factory pattern failing - c++11

I am new to c++ and am trying a basic factory pattern in C++11 but is failing with error: 'X' does not refer to a value.
Any suggestions?
Test Code:
X instance = X.createNewInstance();
Original Class
class X
{
public:
static X createNewInstance() {
return X();
};
void foo() ;
private:
X(){};
};

You have to call static member functions with ::
X instance = X::createNewInstance();

Related

How do you assign a default value to a <functional> object?

I pass a function pointer to a function using functional, and use a constructor initialization to save it in a local variable for later use. How do I assign a default value to the parameter.
Example:
function<void()> BEGINFILE;
somefunct(function<void()> BEGINFILE): BEGINFILE(BEGINFILE) {}
But I can't seem to do:
void nullfunct() {}
function<void()> BEGINFILE;
void somefunct(function<void()> BEGINFILE = nullfunct): BEGINFILE(BEGINFILE) {}
or:
void nullfunct() {}
function<void()> BEGINFILE;
somefunct(function<void()> BEGINFILE) {
BEGINFILE = BEGINFILE;
}
I've also read that functional is deprecated/removed in C++17. I've tried to find what C++17 does without success.
I suppose that somefunct is a class (or a struct) and that with
void somefunct(function<void()> BEGINFILE): BEGINfILE(BEGINFILE) {}
do you mean a constructor of somefunct.
First (secondary) problem: constructors doesn't return values, so remove the initial void.
For the main problem I suppose that you have the problem when the default function (nullfunct()) is a non static member function.
I mean, in this case
struct somefunct
{
void nullfunct() {}
std::function<void()> bf;
somefunct (std::function<void()> bf0 = nullfunct) : bf{bf0}
{ }
};
Unfortunately, a non-static member function is something strange, very different from a regular function, and you can't assign it to a std::function.
I see three ways to solve this problem.
transform it in a static one
A static member function doesn't depend from an instance of the class so is the same type of object of a regular function and can be assigned to a std::function, so if you can transform nullfunct() in a static member, you can write
struct somefunct
{
static void nullfunct() {}
std::function<void()> bf;
somefunct (std::function<void()> bf0 = nullfunct) : bf{bf0}
{ }
};
make nullfunct() an regular function.
If you can make nullfunct() a regular (not member of a class or struct) function, it becomes compatible with std::function, so
void nullfunct() {}
struct somefunct
{
std::function<void()> bf;
somefunct (std::function<void()> bf0 = nullfunct) : bf{bf0}
{ }
};
initialize with an empty function and set with a wrapping lambda
If you can't transform somefunct() in a static member function (way 1) or in regular function (way 2), you can wrap the call of somefunct() in a lambda function that you can assign to your std::function.
Unfortunately, this lambda function has to capture the this pointer and can't do it if is defined as a default value for the argument of the constructor so the way I see is initialize the std::function with an empty std::function and, in the body of the constructor, if the member contains an empty function, assign the lambda.
I mean
struct somefunct
{
void nullfunct() {}
std::function<void()> bf;
somefunct (std::function<void()> bf0 = {}) : bf{bf0}
{ if ( not bf ) bf = [this]{ this->nullfunct(); }; }
};

Actual function call count doesn't match EXPECT_CALL(mockImplClass, receive(_, _))

I am facing problem while running gtest for the following code sample.
ignore header includes as its compilable and running fine.
Error:
GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: receive(0x7ffcee4fc990, 0x7ffcee4fc900)
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
/data/home/sipadhy/unit_test_research/gTest/ImplClassTest.cpp:174: Failure
Actual function call count doesn't match EXPECT_CALL(mockImplClass, receive(_, _))...
Expected: to be called at least once
Actual: never called - unsatisfied and active
Sample Code:
// Main Class where function to be mocked
class ImplClass
{
public:
virtual int receive(structX* x, structY* y){ // some logic }
};
// An intermidiate class which calls the main class
class IntermidiateClass
{
std::shared_ptr<ImplClass> implClassPtr = nullptr;
public:
setImplClassptr(std::shared_ptr<ImplClass> ptr)
{
implClassPtr = ptr;
}
int getValue()
{
structX x;
structY y;
return(implClassPtr->receive(x, y));
}
};
// Mock Class
class MockImplClass: public ImplClass
{
public:
MOCK_METHOD2(receive, int(structX, structY));
}
// Test case
TEST(MyTest, TEST1)
{
MockImplClass mockImplClass;
IntermidiateClass intermidiateObj;
intermidiateObj.setImplClassptr(std::make_shared<MockImplClass>());
EXPECT_CALL(mockImplClass, receive(_, _))
.Times(AtLeast(1))
.WillRepeatedly(Return(1));
int retVal = intermidiateObj.getValue();
}
Thanks,
Siva
You create a brand new object of the MockImplClass class here:
std::make_shared<MockImplClass>()
Thus your first created object
MockImplClass mockImplClass;
never gets used to call receive()

Why can't Vala connect signals to delegates?

I used to think that a delegate behaves like a method reference in Vala. However, I don't understand why the following code doesn't work:
class Bar {
public signal void bar_signal();
}
class Foo : Object {
public Foo( int i, Bar bar ) {
bar.bar_signal.connect( bar_handler( i + 1 ) );
}
public delegate void Handler();
private static Handler bar_handler( int j ) {
return () =>
{
stdout.printf( "handler: %d\n", j );
};
}
}
public static void main( string[] args ) {
Bar bar = new Bar();
new Foo( 1, bar ); // will be finalized immediately
bar.bar_signal();
}
The idiom of this code is actually quite typical in JavaScript, which makes heavy use of closures. Sadly, valac says:
Test.vala:8.33-8.45: error: Argument 1: Cannot convert from Foo.Handler to Bar.bar_signal
At first, I thought that this might be due to the following incompatibility of delegate types:
Instance and static delegate instances are not interchangeable.
However, the error doesn't change if I put a static into the declaration of the delegate.
I searched the web but only came across an old mailing list entry from 2009, which says that this is a bug in Vala. Is that right? And if so: How can it be that this bug still isn't fixed, 7 years later?
It is indeed a known bug: https://bugzilla.gnome.org/show_bug.cgi?id=604781
A workaround is to invoke it using a closure:
bar.bar_signal.connect( () => { bar_handler( i + 1 ); } );

C++ Initialize abstract base class protected member for all derived classes

Is it possible to initialize abstract base class' protected member for all derived objects without writing the same initializer list in all derived class constructors? So that it acts like a static member for all derived objects. What I want is something like this (except it doesn't work) Read it like a pseudo code:
A.h
class A {
public:
A(string fn);
virtual ~A();
virtual void open_file() = 0;
protected:
string fileName;
};
A.cpp
A::A(string fn) : fileName {fn} {} //Initializer list is written only once here
A::~A() {}
B.h
class B : public A {
public:
B();
~B();
void open_file() const override;
};
B.cpp
B::B() {} //No initializer list for A::fileName here
void B::open_file() const {
ifstream SomeFile(fileName); //Use base class' protected member
..... //Do some stuff with open file
}
And imagine there's also a C derived class without an initializer list for A here that has a different overriden open_file function..
main.cpp
string fname = {"foo.txt"};
A* APtr = new B(fname); //This initializes A's fileName for all derived objects as "foo.txt"
Aptr->open_file(); //B opens foo.txt
fname = "bar.txt";
A* A2Ptr = new C(fname); //Now fileName that both B and C consume is changed to "bar.txt"
A2Ptr->open_file(); //C opens bar.txt
APtr->open_file(); //B now opens bar.txt
You deklared the constructor from B: B(); but you try to use it A* APtr = new B(fname); So the compiler can't find any matching constructor.
initialize abstract base class' protected member for all derived objects without writing the same initializer list in all derived class
Why not?
A.hpp
class A
{
public:
A( string fn = "") : fileName(fn){} // you can give an default path if prefered.
};
B.hpp
class B : public A
{
public:
B( string fn = "") : A( fn ) {} //c++11 feature: call base constructor.
}
Other possible solutions were:
global variable (dirty and unsafe! - Please don't do it.)
static variable in A. But you can only open one file the same time.
give A setter and getter for fileName. And use it that way:
main.cpp
B* b = new B();
b->setFileName("foo.txt");
b->openFile();

Substituting `find_if` function

I wrote a class method using STL find_if. The code is the following:
void
Simulator::CommunicateEvent (pEvent e)
{
pwEvent we (e);
std::list<pEvent> l;
for (uint32_t i = 0; i < m_simulatorObjects.size (); i++)
{
l = m_simulatorObjects[i]->ProcessEvent (we);
// no action needed if list is empty
if (l.empty ())
continue;
// sorting needed if list comprises 2+ events
if (l.size () != 1)
l.sort (Event::Compare);
std::list<pEvent>::iterator it = m_eventList.begin ();
std::list<pEvent>::iterator jt;
for (std::list<pEvent>::iterator returnedElementIt = l.begin ();
returnedElementIt != l.end ();
returnedElementIt++)
{
// loop through the array until you find an element whose time is just
// greater than the time of the element we want to insert
Simulator::m_eventTime = (*returnedElementIt)->GetTime ();
jt = find_if (it,
m_eventList.end (),
IsJustGreater);
m_eventList.insert (jt, *returnedElementIt);
it = jt;
}
}
}
Unfortunately, I later discovered that the machine that will run the code is equipped with the libstdc++ library version 4.1.1-21, which apparently is lacking find_if. Needless to say, I cannot upgrade the library, nor can I ask someone to do it.
When compiling, the error I get is:
simulator.cc: In member function ‘void sim::Simulator::CommunicateEvent(sim::pEvent)’:
simulator.cc:168: error: no matching function for call to ‘find_if(std::_List_iterator<boost::shared_ptr<sim::Event> >&, std::_List_iterator<boost::shared_ptr<sim::Event> >, sim::Simulator::<anonymous struct>&)’
simulator.cc: In static member function ‘static void sim::Simulator::InsertEvent(sim::pEvent)’:
simulator.cc:191: error: no matching function for call to ‘find_if(std::_List_iterator<boost::shared_ptr<sim::Event> >&, std::_List_iterator<boost::shared_ptr<sim::Event> >, sim::Simulator::<anonymous struct>&)’
make: *** [simulator.o] Error 1
How can I solve the problem?
I thought I could define a find_if function as described here. However, I have some concerns:
What about performance? The function that makes use of find_if needs to be as efficient as possible.
How can I do conditional compilation? I couldn't find a macro telling the version of the libstdc++ installed.
What are your thoughts about it?
TIA,
Jir
References
Source files: simulator.h and simulator.cc
Solution
Defined IsJustGreater outside the Simulator class and declared IsJustGreater_s friend of Simulator:
struct IsJustGreater_s : public std::unary_function<const pEvent, bool> {
inline bool operator() (const pEvent e1) {return (e1->GetTime () > Simulator::m_eventTime);}
} IsJustGreater;
Called IsJustGreater in find_if this way:
jt = find_if (it, m_eventList.end (), sim::IsJustGreater);
From the error, it appears that you're attempting to use an anonymous type as the argument. I do not believe anonymous types are allowed to be template arguments.
From the error, I believe you have something like this:
class Simulator {
struct {
bool operator(const pEvent& p) { ... } ;
} IsJustGreater;
}
what you want is to give it a name and then change the find_if to instantiate the class (see below)
class Simulator {
// class is now an inner named-class
struct IsJustGreater {
bool operator(const pEvent& p) { ... } ;
};
}
// This is how you use the class
jt = std::find_if(it, m_eventList.end(), IsJustGreater() );
I see that you're using the std:: qualifier before std::list but not std::find_if. Try putting the std:: in front so that the compiler can find it within the namespace.

Resources