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(); }; }
};
Related
I have a struct A that inherits from other classes (which I'm not allowed to change). Inside A and it's methods I can call inherited methods (lets say A_method(int i), for example) without problem but when I tried to write a nested struct (lets say In) and call A_method(int i) and there is were I'm stuck.
The initial code looks like this, and I can't change it, is some kind of college assigment.
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
virtual void play () {
}
};
RegisterPlayer(PLAYER_NAME);
Then I tried this:
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
//My code
struct In {
int x;
void do_smthing() {
A_method(x);
}
}
virtual void play () {
}
};
RegisterPlayer(PLAYER_NAME);
Ok, from a beginning I knew I could't do this, for In to see it's parent class it should have a pointer to it but In is a often instantiated object in my code and I wanted to avoid passing this constantly to a constructor so I tried this aproach:
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
//My code
static struct Aux
A* ptr;
Aux(A* _p) { ptr = _p; }
} aux;
struct In {
int x;
void do_smthing() {
aux.ptr->A_method(x);
}
}
virtual void play () {
//the idea is to call do_smthing() here.
}
};
RegisterPlayer(PLAYER_NAME);
What I want to avoid (if possible) is something like this:
struct In {
int x;
A* ptr;
In (A* _p) : ptr(_p) {}
void do_smthing() {
ptr->A_method(x);
}
}
The main reason for this: I have more struct definitions and they they are instantiated multiple times through the rest of the (omitted) code, and I don't like the idea of seeing In(this) so many times.
I don't know if I'm completly missing something or what I want to do it's just not possible... Please ask for clarifications if necessary.
(Also, performance is kind of critical, my code will be tested with limited CPU time so I kinda have to avoid expensive approachs if possible. Using C++11)
There is no way you can skip passing the this pointer. Instead, you could create a helper function in A:
template <typename InnerType, typename ...Params>
InnerType makeInner(Params&&... params)
{
return InnerType(this, std::forward<Params>(params)...);
}
Then you can use
auto * a = A::factory();
auto inner = a->makeInner<A::In>();
I have some suggestions which are not directly related to you question but may help:
A::facotry() returns a std::unique_ptr<A> instead of raw pointer
Try to describe what problem you are trying to solve. I have a strong feeling that there can be a better design other than creating many nested structs.
I don't see passing a this pointer could have any impact on the performance. The more important thing is to identify the path that is latency-sensitive and move expensive operations out of those paths.
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()
There is a custom defined map, with an element std::function()>.
The lambda code is working, but I don't know how to expand it to a normal formation. The code is following.
class TestA{
public:
TestA() {}
~TestA() {}
TestA(const TestA &) {}
static void print()
{
cout << __FUNCTION__ << endl;
return;
}
};
void testComplexMap1()
{
typedef map<string, std::function<std::unique_ptr<TestA>()>> TempMap;
TempMap m;
// the lambda format code, it works
//m.insert({ "TestA", []() {return std::unique_ptr<TestA>(new TestA());}});
// I want to expand it, but failed.
TestA *t = new TestA();
//function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t));
function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t)()); //warning here
//m.emplace("TestA", fp); // compile error here
}
Any help will be greatly appreciated.
fp is not initialized with a function so compilation fails.
You can expand it like this:
TestA *t = new TestA();
std::unique_ptr<TestA> UT(t);
auto func = [&]() { return move(UT);};
std::function<std::unique_ptr<TestA>()> fp(func);
m.emplace("TestA", fp);
See DEMO.
In C++ everything that looks like it could be a declaration is treated as such.
This means the line
function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t)());
is interpreted as:
fp is the declaration of a function returning an std::function<unique_ptr<TestA>()> and expecting a parameter called t which is a function pointer to a function returning a std::unique_ptr<TestA> and getting no parameter. (Which is not what you intended.)
This also means that the t in this line is not the same t as in the previous line.
You have to pass fp something that is actually callable like this:
std::unique_ptr<TestA> f() {
return std::make_unique<TestA>();
}
void testComplexMap1() {
// ...
function<unique_ptr<TestA>()> fp(f);
m.emplace("TestA1", fp);
}
If you want to add a function to the map that wraps an existing pointer into a unique_ptr you would need either a functor:
class Functor {
public:
Functor(TestA * a) : m_a(a) {}
~Functor() { delete m_a; }
std::unique_ptr<TestA> operator()(){
auto x = std::unique_ptr<TestA>(m_a);
m_a = nullptr;
return std::move(x);
}
private:
TestA * m_a;
};
void testComplexMap1() {
//...
TestA * t = new TestA();
m.emplace("TestA", Functor(t));
}
Or a lambda with capture:
void testComplexMap1() {
//...
TestA * t = new TestA();
m.emplace("TestA", [t](){ return std::unique_ptr<TestA>(t); });
}
The lamda is translated more or less to something like the Functor class. However in each case you have to be really careful: The functions in the map that encapsulate an existing pointer into a std::unique_ptr can and should only be called once.
If you don't call them, memory allocated for t won't be freed. If you call them more than once you get either a std::unique_ptr to nullptr (in my Functor class variant) or a more than one std::unique_ptr tries to manage the same memory region (in the lambda with capture variant), which will crash as soon as the second std::unique_ptr is deleted.
In short: I would advice against writing code like this and only put functions in the map that are callable multiple times.
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();
Whats the difference between bound and unbound delegates?
heres how you create delegates of both types:
// bound delegate declaration
public delegate void Handler(int value);
// create a bound delegate
Handler^ handler = gcnew Handler(HandlerClass::Fun1);
// unbound delegate declaration
public delegate void UBHandler(ThisClass^, int value);
// create an unbound delegate
UBHandler^ ubh = gcnew UBHandler(&ThisClass::Sum);
these are nearly the same. then, you can create constructors for bound delegates that consist of two parameters:
HandlerClass^ obj = gcnew HandlerClass;
Handler^ handler2 = gcnew Handler (obj, & HandlerClass::Fun3);
it means that you can use this particular delegate to invoke a function that is not static (is an instance). but then you can do the same with unbound delegates. Here’s how you might call the ubh delegate:
ThisClass^ obj = gcnew ThisClass(99.0);
ubh(obj, 5);
so whats the point of having both types?
// code for HandlerClass
public ref class HandlerClass
{
public:
static void Fun1(int m)
{ Console::WriteLine(L”Function1 called with value {0}”, m); }
static void Fun2(int m)
{ Console::WriteLine(L”Function2 called with value {0}”, m); }
void Fun3(int m)
{ Console::WriteLine(L”Function3 called with value {0}”, m+value); }
void Fun4(int m)
{ Console::WriteLine(L”Function4 called with value {0}”, m+value); }
HandlerClass():value(1){}
HandlerClass(int m):value(m){}
protected:
int value;
};
The difference is the exact time the target object value is generated. With a bound delegate it is generated when you create the delegate object and it is forever unchanging after that. An unbound delegate doesn't store the object reference, it is generated at the time the delegate is invoked. The same delegate can then be used to invoke the target method with different objects.
Unbound delegates are a match with the syntax of C++ member function pointers. There is no direct equivalent for bound delegates in C++.