c++ move semantics where allegedly there shouldn't be benefit - c++

I needed to use some class today that followed this basic design:
class Task {
public:
Task() {
Handler::instance().add(this);
}
virtual void doSomething() = 0;
};
class Handler {
std::vector<Task*> vec;
//yea yea, we are locking the option to use default constructor etc
public:
static Handler& instance() {
static Handler handler;
return handler;
}
void add(Task* task) {
vec.push_back(task);
}
void handle() {
for (auto t : vec) {
t->doSomething();
}
}
};
template <class T, int SIZE>
class MyTask : public Task {
T data[SIZE];
public:
virtual void doSomething() {
// actually do something
}
};
//somewhere in the code:
Handler::instance().handle();
now, my class is something like
class A {
MyTask<bool, 128> myTask;
public:
A(int i) {}
};
the way I wanted to do it is having a map where instances of A are values
static std::map<int, A> map = {
{42, A(1948)},
{88, A(-17)}
};
first to clarify something - this code needs to run on a real time embedded system so I'm not allowed to allocate memory using new for several legacy reasons.
My problem was that the actual objects in the map weren't the ones I explicitly created and so they didn't register in the Handler class (so I didn't get the benefit of the Handler::handle calls).
I tried figuring a nice way to solve this without doing something ugly like first creating an array of A then only point to these objects in the map for example.
I never used move semantics before but I've read little bit about them and thought they can be my solution.
however, after reading this answer (specificaly the very first example) it seemed that I can't really benefit anything from using move semantics.
I tried it anyway (coz why the heck not...) and did something like this instead:
static std::map<int, A> map = {
{42, std::move(A(1948))},
{88, std::move(A(-17))}
};
now for my surprise the copy constructor of MyTask was still called (I put print in it to verify) but for some reason now the handler registration worked well and my instances enjoyed the doSomething() calls.
I tried reading more thoroughly about std::move to understand what exactly happened there but couldn't find the answer.
can anyone explain it? does std::move moves the this pointer somehow? or maybe it just caused the registration to happen correctly somehow and had nothing real to do with the moving attempt
thanks
edit:
to further clarify what I'm asking:
I understand the use of std::move was not contributing to what's being done there.
But for some reason it did get my objects in the map to get the doSomething() calls through the handler. I'm looking for that reason
on a side note as it probably belongs to a different question - is there any decent way to initialize a map this way without the overhead of creating each object twice?

Your question has a lot more in it than it needs to but I think I understand the root question here. The std::map constructor receives an initialization_list, you're calling (5) from this list. Objects are copied out of an initializer_list when iterating over it rather than moved because a copy of an initializer_list doesn't copy the underlying objects. The same affects other std containers, here is an example with vector to demonstrate. (live link)
#include <vector>
#include <iostream>
struct Printer {
Printer() { std::cout << "default ctor\n"; }
Printer(const Printer&) { std::cout << "copy\n"; }
Printer(Printer&&) { std::cout << "move\n"; }
};
int main() {
std::vector<Printer> v = {Printer{}};
}
if you use {std::move(Printer{})} you'll add another move into the mix that the compiler can't easily get optimize away.

Related

Is it is possible to construct container and filled data into it in one line using C++03?

Suppose I have a Container.
template<typename Type>
class Container
{
public:
Container(int size_)
{
size=size_;
data = new Type[size];
}
~Container()
{
delete [] data;
}
private:
int size;
Type* data;
};
I want construct the container and fill data into it in one line like this using C++03
// very easy to implement using C++11 std::initializer_list
Container<int> container{100,200,300}
or
Container<int> container(100,200,300)
or
// other one line solution
after do this, data[0]=100,data[1]=200,data[2]=300.
Thanks for your time.
Appendix
Similiar question is
How to fill data into container at once without temp variable in C++03
Evg already give the answer can implement a two lines solution.
Container<int> container(3);
container << 100, 200, 300;
I still wonder is there exist the one line solution?
The answer you link can almost do that. You only need a minor modification and that is: You need to make your container resizable. This is actually the major issue. Once you have that, adapting the solution is minor. Write a insert method that reallocates the memory and adjusts the size then only minor modifications on the proposed solution are necessary.
There is one caveat, and this is you cannot call the constructur call methods on the constructed object and assign it to a variable in the same line without a copy. For that it is possible to provide a conversion from Proxy to Container. I would rethink if putting something on a single line is really worth this cost, when it can be done much easier on two lines.
I didn't include the implementation of insert, because that would be sort of a different question:
#include <iostream>
template<typename Type>
class Container {
private:
struct Proxy {
Container* container;
Proxy(Container* container) : container(container) {}
Proxy& operator,(Type value) {
container->insert(value);
return *this;
}
operator Container() { return *container; }
};
public:
// ...
void insert(const Type& value) {
std::cout << value;
}
Proxy operator<<(Type value) {
insert(value);
return Proxy(this);
}
};
int main() {
Container<int> container = (Container<int>() << 1,2,3);
}
Output:
123
PS:
The problem is that, there is Container x={1,2,3,....,1000} everywhere in my project using C++11. Now, I must omove to C++03, and there is no std::itializer_list
Yes that is a problem. I suppose 1,2,3,...1000 is just an oversimplified example, otherwise you could use something similar to std::iota to fill the container (also only avaible since C++11, but not too difficult to implement). If that is the actual problem and you are looking for a temporary hack I would rather use plain arrays and construct the container from that:
int temp[] = {1,2,3,4,5 ....};
Container<int> x( &temp[0], &temp[999]);

Can I use std::bind to convert a pointer to member function into a pointer to function?

I want to pass a member function as a call-back. The call back is a basic function pointer.
So I have something like:
h file:
void (*pRequestFunc) (int someint) = 0;
void RegisterRequestCallBack(void (*requestFunc) (int someint))
{
pRequestFunc = requestFunc;
}
class A
{
void callBack(int someint);
}
Cpp File:
RegisterRequestCallBack(&A::callBack); // This does not work.
Note I have tried to extract this example from my larger example and cut out all the other stuff - so it might not be perfect.
The problem, as far as I understand, is that member function pointers really (under the hood) have an extra parameter (and instance - i.e. this) and are not compatible with normal function pointers.
the RegisterRequestCallBack() is in reality not my code - and so I can't change that.
So I read that boost::bind can do what I need - and I am hoping c++11 std::bind can do the same - but I could not figure out how to use it to effectively get a standard function pointer from a member function pointer...
I was going for something like:
std::bind(&A::callBack) ... that is about as far as I got, my understanding of the examples online is poor :(
NathanOliver's comment is correct, and your suspicion is mostly correct. Exactly how pointers to member functions work is not specified, but including this as a hidden argument mostly works. You just need a bit of extra work for inheritance and pointers to virtual functions (yes, you can take their address too).
Now, often callbacks include a void* parameter under your control, which you can use to pass a A*. In those cases, you can write a wrapper (static) function that casts the void* back to A* and does the actual call to &A::callback.
That's not the case here. Registration takes a single function, without data. To get this to work in real-life situations, you have to resort to drastic solutions - not portable C++. One such method is to dynamically generate assembly (!). You create - at runtime - the compiled equivalent of
void __trampoline_0x018810000 (int i)
{
A* __this = reinterpret_cast<A*>(0x018810000);
__this->callback(i);
}
As you can see, you have to generate one trampoline for every A* value, and managing lifetimes of these is a major pain.
To be able to bind to a member function you need to do:
std::function<void(int)> function = std::bind(&A::foo, this, std::placeholders::_1);
Or in your case:
RegisterRequestCallBack(std::bind(&A::callback, this, std::placeholders::_1));
But in my opinion the clearest way to achieve this is to use lambda functions. Here you have an example to for doing something similar that could inspire you:
#include <array>
#include <map>
#include <vector>
#include <functional>
#include <iostream>
class TaskManager {
public:
using task_t = std::function<void()>;
void run();
void addTask(task_t task);
private:
std::vector<task_t> _tasks;
};
void TaskManager::run() {
for (auto& task : _tasks) {
task();
}
}
void TaskManager::addTask(task_t task) {
_tasks.push_back(task);
}
class Example {
public:
Example(){
taskManager.addTask([this]() {
task1();
});
taskManager.addTask([this,a=int(4)](){
task2(a);
});
}
TaskManager taskManager;
private:
void task1(){ std::cout << "task1!\n"; }
void task2(int a){ std::cout << "task2 says: " << a << "\n"; }
};
int main() {
Example example;
example.taskManager.run();
}
which outputs:
task1!
task2 says: 4

How do I (elegantly) assign reference members according to a char alias?

Disclaimer
I don't actually propose to apply this design anywhere, but I've been curious nonetheless how one would implement this in C++, in particular given C++'s lack of reflection. (I'm simultaneously learning and experimenting with C++11 features, so please do use C++11 features where helpful.)
The Effect
What I want to achieve is almost purely cosmetic.
I'd like a class that binds itself to an arbitrary number of, say, vectors, using referenced members (which, as I understand, must be initialized during construction), but provides "aliases" for accessing these vectors as members.
To give a minimal example, I want this to work—
std::vector<int> one;
std::vector<int> two;
std::vector<int> three;
Foo foo(std::make_pair('B', one),
std::make_pair('D', two),
std::make_pair('F', three));
foo.DoSomething();
where
class Foo
{
public:
// I'm using variadic templates here for sake of learning,
// but initializer lists would work just as well.
template <typename ...Tail>
Foo(std::pair<char, std::vector<int>&> head, Tail&&... tail) // : ???
{
// ???
}
virtual void DoSomething()
{
D.push_back(42);
std::cout << D[0] << std::endl;
}
private:
std::vector<int> A&, B&, C&, D&, E&, F&, G&; // and so on...
}
and also so that
std::cout << one[0] << std::endl; // outputs 42 from outside the class...
But you refuse to answer unless you know why...
Why would anyone want to do this? Well, I don't really want to do it, but the application I had in mind was something like this. Suppose I'm building some kind of a data analysis tool, and I have clients or operations people who know basic logic and C++ syntax, but don't understand OOP or anything beyond CS 101. Things would go a lot smoother if they could write their own DoSomething()s on the fly, rather than communicate every need to developers. However, it's not realistic to get them to set up UNIX accounts, teach them how to compile, and so on. So suppose instead I'd like to build an intranet web interface that lets them write the body of DoSomething() and configure what datasets they'd like to "alias" by an uppercase char, and upon submission, generates C++ for a child class of Foo that overrides DoSomething(), then builds, runs, and returns the output. (Suspiciously specific for a "hypothetical," eh? :-) Okay, something like this situation does exist in my world—however it only inspired this idea and a desire to explore it—I don't think it'd be worth actually implementing.) Obviously, this whole uppercase char ordeal isn't absolutely necessary, but it'd be a nice touch because datasets are already associated with standard letters, e.g. P for Price, Q for Quantity, etc.
The best I can do...
To be honest, I can't figure out how I'd make this work using references. I prefer using references if possible, for these reasons.
With pointers, I guess I'd do this—
class Foo
{
public:
template <typename ...Tail>
Foo(std::pair<char, std::vector<int>*> head, Tail&&... tail)
{
std::vector<int>[26] vectors = {A, B, C, D, E, F, G}; // and so on...
// I haven't learned how to use std::forward yet, but you get the picture...
// And dear lord, forgive me for what I'm about to do...
vectors[tail.first - 65] = tail.second;
}
virtual void DoSomething()
{
D->push_back(42);
std::cout << (*D)[0] << std::endl;
}
private:
std::vector<int> A*, B*, C*, D*, E*, F*, G*; // and so on...
}
But even that is not that elegant.
Is there a way to use references and achieve this?
Is there a way to make this more generic, e.g. use pseudo-reflection methods to avoid having to list all the uppercase letters again?
Any suggestions on alternative designs that would preserve the primary goal (the cosmetic aliasing I've described) in a more elegant or compact way?
You may use something like:
class Foo
{
public:
template <typename ...Ts>
Foo(Ts&&... ts) : m({std::forward<Ts>(ts)...}),
A(m.at('A')),
B(m.at('B'))
// and so on...
{
}
virtual void DoSomething()
{
A.push_back(42);
std::cout << A[0] << std::endl;
}
private:
std::map<char, std::vector<int>&> m;
std::vector<int> &A, &B; //, &C, &D, &E, &F, &G; // and so on...
};
but that requires that each vector is given, so
Foo(std::vector<int> (&v)[26]) : A(v[0]), B(v[1]) // and so on...
{
}
or
Foo(std::vector<int> &a, std::vector<int> &b /* And so on */) : A(a), B(b) // and so on...
{
}
seems more appropriate.
Live example.
And it seems even simpler if it is the class Foo which owns the vector, so you will just have
class Foo
{
public:
virtual ~Foo() {}
virtual void DoSomething() { /* Your code */ }
std::vector<int>& getA() { return A; }
private:
std::vector<int> A, B, C, D; // And so on
};
and provide getters to initialize internal vectors.
and then
std::vector<int>& one = foo.GetA(); // or foo.A if you let the members public.

Trying to store objects in a vector

I'm quite new to C++ and I am trying to store objects inside a std::vector like this:
Event.h:
//event.h
class Event
{
public:
Event();
Event(std::string name);
~Event();
void addVisitor(Visitor visitor);
private:
std::vector<Visitor> m_visitors;
};
Event.cpp:
//event.cpp
Event::Event() :
m_name("Unnamed Event")
{
}
Event::Event(std::string name) :
m_name(name)
{
}
void Event::addVisitor(Visitor visitor)
{
this->m_visitors.push_back(visitor);
}
void Event::listVisitors()
{
std::vector<Visitor>::iterator it;
for(it = this->m_visitors.begin();it != this->m_visitors.end(); ++it)
{
std::cout << it->getName() << std::endl;
}
}
Visitor.h:
//visitor.h
class Visitor
{
public:
Visitor();
Visitor(std::string name);
~Visitor();
std::string getName() const;
void listVisitors();
private:
std::string m_name;
};
Visitor.cpp:
//visitor.cpp
Visitor::Visitor() :
m_name("John Doe")
{
}
Visitor::Visitor(std::string name) :
m_name(name)
{
}
std::string Visitor::getName() const
{
return m_name;
}
main.cpp:
//main.cpp
int main()
{
Event *e1 = new Event("Whatever");
Visitor *v1 = new Visitor("Dummy1");
Visitor *v2 = new Visitor("Dummy2");
e1->addVisitor(*v1);
e1->addVisitor(*v2);
}
If I do it like this I would have to add a copy constructor which would make a deep copy so the object gets copied properly into the vector. I'm looking for a way around it by only storing pointers to the objects in a vector.
I already tried it with std::vector<std::unique_ptr<Visitor> > m_visitors, but then I got some errors when calling addVisitor in main.cpp. Of course I changed the declaration of the class members accordingly.
How would an appropriate declaration of the members and the member function look like to make it work?
Stylistically, if you are passing pointers, just accept pointers as the function arguments.
What's happening in the example code above is that the visitors are getting copied to become function arguments and the pointers you had are unreferenced by anything outside of the main function.
I can't speak to what the errors are that you're seeing as you didn't describe them but it probably has to do with incompatible types.
Just get rid of the news because for these data structures they're unnecessary.
int main()
{
Event e1("Whatever");
Visitor v1("Dummy1");
Visitor v2("Dummy2");
e1.addVisitor(v1);
e1.addVisitor(v2);
}
I would suggest that if you don't know how to use pointers you couldn't possibly want to store them instead (they're a hassle IMO to store in the vector when copying by value works just fine).
The compiler generated copy constructor should work just fine.
No manual deep copy required, because you are quite correctly using std::string, which supports RAII.
However, your main function has three memory leaks — there is no need to use new there anyway, so simply don't.
General rule of thumb:
If, at any time T, you're thinking of introducing more pointers into your code, then you're probably going in the wrong direction.

what is a good place to put a const in the following C++ statement

Consider the following class member:
std::vector<sim_mob::Lane *> IncomingLanes_;
the above container shall store the pointer to some if my Lane objects. I don't want the subroutins using this variable as argument, to be able to modify Lane objects.
At the same time, I don't know where to put 'const' keyword that does not stop me from populating the container.
could you please help me with this?
thank you and regards
vahid
Edit:
Based on the answers i got so far(Many Thanks to them all) Suppose this sample:
#include <vector>
#include<iostream>
using namespace std;
class Lane
{
private:
int a;
public:
Lane(int h):a(h){}
void setA(int a_)
{
a=a_;
}
void printLane()
{
std::cout << a << std::endl;
}
};
class B
{
public:
vector< Lane const *> IncomingLanes;
void addLane(Lane *l)
{
IncomingLanes.push_back(l);
}
};
int main()
{
Lane l1(1);
Lane l2(2);
B b;
b.addLane(&l1);
b.addLane(&l2);
b.IncomingLanes.at(1)->printLane();
b.IncomingLanes.at(1)->setA(12);
return 1;
}
What I meant was:
b.IncomingLanes.at(1)->printLane()
should work on IncomingLanes with no problem AND
b.IncomingLanes.at(1)->setA(12)
should not be allowed.(In th above example none of the two mentioned methods work!)
Beside solving the problem, I am loking for good programming practice also. So if you think there is a solution to the above problem but in a bad way, plase let us all know.
Thaks agian
A detour first: Use a smart pointer such shared_ptr and not raw pointers within your container. This would make your life a lot easy down the line.
Typically, what you are looking for is called design-const i.e. functions which do not modify their arguments. This, you achieve, by passing arguments via const-reference. Also, if it is a member function make the function const (i.e. this becomes const within the scope of this function and thus you cannot use this to write to the members).
Without knowing more about your class it would be difficult to advise you to use a container of const-references to lanes. That would make inserting lane objects difficult -- a one-time affair, possible only via initializer lists in the ctor(s).
A few must reads:
The whole of FAQ 18
Sutter on const-correctness
Edit: code sample:
#include <vector>
#include <iostream>
//using namespace std; I'd rather type the 5 characters
// This is almost redundant under the current circumstance
#include <vector>
#include <iostream>
#include <memory>
//using namespace std; I'd rather type the 5 characters
// This is almost redundant under the current circumstance
class Lane
{
private:
int a;
public:
Lane(int h):a(h){}
void setA(int a_) // do you need this?
{
a=a_;
}
void printLane() const // design-const
{
std::cout << a << std::endl;
}
};
class B
{
// be consistent with namespace qualification
std::vector< Lane const * > IncomingLanes; // don't expose impl. details
public:
void addLane(Lane const& l) // who's responsible for freeing `l'?
{
IncomingLanes.push_back(&l); // would change
}
void printLane(size_t index) const
{
#ifdef _DEBUG
IncomingLanes.at( index )->printLane();
#else
IncomingLanes[ index ]->printLane();
#endif
}
};
int main()
{
Lane l1(1);
Lane l2(2);
B b;
b.addLane(l1);
b.addLane(l2);
//b.IncomingLanes.at(1)->printLane(); // this is bad
//b.IncomingLanes.at(1)->setA(12); // this is bad
b.printLane(1);
return 1;
}
Also, as Matthieu M. suggested:
shared ownership is more complicated because it becomes difficult to
tell who really owns the object and when it will be released (and
that's on top of the performance overhead). So unique_ptr should be
the default choice, and shared_ptr a last resort.
Note that unique_ptrs may require you to move them using std::move. I am updating the example to use pointer to const Lane (a simpler interface to get started with).
You can do it this way:
std::vector<const sim_mob::Lane *> IncomingLanes_;
Or this way:
std::vector<sim_mob::Lane const *> IncomingLanes_;
In C/C++, const typename * and typename const * are identical in meaning.
Updated to address updated question:
If really all you need to do is
b.IncomingLanes.at(1)->printLane()
then you just have to declare printLane like this:
void printLane() const // Tell compiler that printLane doesn't change this
{
std::cout << a << std::endl;
}
I suspect that you want the object to be able to modify the elements (i.e., you don't want the elements to truly be const). Instead, you want nonmember functions to only get read-only access to the std::vector (i.e., you want to prohibit changes from outside the object).
As such, I wouldn't put const anywhere on IncomingLanes_. Instead, I would expose IncomingLanes_ as a pair of std::vector<sim_mob::Lane *>::const_iterators (through methods called something like GetIncomingLanesBegin() and GetIncomingLanesEnd()).
you may declare it like:
std::vector<const sim_mob::Lane *> IncomingLanes_;
you will be able to add, or remove item from array, but you want be able to change item see bellow
IncomingLanes_.push_back(someLine); // Ok
IncomingLanes_[0] = someLine; //error
IncomingLanes_[0]->some_meber = someting; //error
IncomingLanes_.erase(IncomingLanes_.end()); //OK
IncomingLanes_[0]->nonConstMethod(); //error
If you don't want other routines to modify IncomingLanes, but you do want to be able to modify it yourself, just use const in the function declarations that you call.
Or if you don't have control over the functions, when they're external, don't give them access to IncomingLanes directly. Make IncomingLanes private and provide a const getter for it.
I don't think what you want is possible without making the pointers stored in the vector const as well.
const std::vector<sim_mob::Lane*> // means the vector is const, not the pointer within it
std::vector<const sim_mob::Lane*> // means no one can modify the data pointed at.
At best, the second version does what you want but you will have this construct throughout your code where ever you do want to modify the data:
const_cast<sim_mob::Lane*>(theVector[i])->non_const_method();
Have you considered a different class hierarchy where sim_mob::Lane's public interface is const and sim_mob::Really_Lane contains the non-const interfaces. Then users of the vector cannot be sure a "Lane" object is "real" without using dynamic_cast?
Before we get to const goodness, you should first use encapsulation.
Do not expose the vector to the external world, and it will become much easier.
A weak (*) encapsulation here is sufficient:
class B {
public:
std::vector<Lane> const& getIncomingLanes() const { return incomingLanes; }
void addLane(Lane l) { incomlingLanes.push_back(l); }
private:
std::vector<Lane> incomingLanes;
};
The above is simplissime, and yet achieves the goal:
clients of the class cannot modify the vector itself
clients of the class cannot modify the vector content (Lane instances)
and of course, the class can access the vector content fully and modify it at will.
Your new main routine becomes:
int main()
{
Lane l1(1);
Lane l2(2);
B b;
b.addLane(l1);
b.addLane(l2);
b.getIncomingLanes().at(1).printLane();
b.getIncomingLanes().at(1).setA(12); // expected-error\
// { passing ‘const Lane’ as ‘this’ argument of
// ‘void Lane::setA(int)’ discards qualifiers }
return 1;
}
(*) This is weak in the sense that even though the attribute itself is not exposed, because we give a reference to it to the external world in practice clients are not really shielded.