I have a complex object that looks something like this:
struct A
{
int a;
}
struct B
{
int b;
vector<A> vecA;
}
I am current printing out a vector of B in the following way:
struct PrintStruct
{
ostream &ostream_;
PrintStruct(ostream &stream) : ostream_(stream) {}
void operator()(const A& elementA)
{
ostream_ << elementA.a;
}
void operator()(const B& elementB)
{
ostream_ << elementB.b;
for_each(elementB.vecA.begin(), elementB.vecA.end(), (*this));
}
}
void print()
{
vector<B> vecB;
for_each(vecB.begin(), vecB.end(), PrintStruct(cout));
}
Is that necessarily the best way to do it? My main point of concern is calling the (*this) in the for_each within the functor itself. Is that safe to do? I think it should be, but I'm not sure if there will be any unintended consequences?
My main point of concern is calling the (*this) in the for_each within the functor itself. Is that safe to do?
It cannot be answered in general but in your case, it is safe.
The call to for_each makes a copy of the PrintStruct object and uses it. The ostream_ member of the copy will be reference the same object as the ostream_ member of the original PrintStruct. There should be no problem with it.
I strongly believe that for_each has mostly outlived itself. I see no benefit in it when compared with range loops. The code actually looks cleaner, more straitghtforward, doesn't require ad-hoc classess or lambdas when used like this:
void print()
{
vector<B> vecB;
for(const auto& elem : vecB) {
std::cout << elem;
}
}
Related
I have the following two classes:
struct A {
A() : state(0) { }
A(int state_arg)
: state{ state_arg } { }
int state;
};
struct B {
B(int state_arg, const int& ref)
: state{ state_arg }, ref{ ref } { }
int state;
const int& ref;
};
I pretend the field ref in the second one to be a reference to an integer in another location, maybe (but not necessary) the field state of some instance of type B.
Now I want to performs some operations over those types, Indeed, I use the boost::variant library.
using my_type = boost::variant<A, B>;
Now when I work with variables of my_type all works as expected. For example:
int main() {
my_type a(A(45));
my_type b(B(45, boost::get<A>(a).state));
A& at = boost::get<A>(a);
B& bt = boost::get<B>(b);
if (at.state == bt.ref) {
std::cout << "AS EXPECTED" << std::endl;
}
// that prints "AS EXPECTED"
}
But when I work with a std::vector of my_type the things go wrong !
int main() {
std::vector<my_type> vec;
vec.push_back(A(45));
vec.push_back(B(45, boost::get<A>(vec[0]).state));
A& at = boost::get<A>(vec[0]);
B& bt = boost::get<B>(vec[1]);
if (at.state == bt.ref) {
std::cout << "SHOULD I EXPECTED THIS ?" << std::endl;
}
// the code doesn't print
}
Now, I want to know what is going on here, i.e
What is occurring that in the code above that the if condition evaluation gives false ?
And is possible, I would like to receive some advice in how to accomplish this tasks.
Thanks in advance.
Problem is that when you add second element to the vector, it reallocates more memory and moves first object to the new location and you have dangled reference. Simple solution would be to reserve enough memory in std::vector in advance to prevent reallocation or use another container that does not move objects. But your original solution has a design flaw - it relies on the fact that object it has reference to should outlive it. But your logic cannot guarantee that so it leads to the issue you see in the std::vector. Same issue could be in the first example if object b would outlive object a somehow. Better solution would be to use smart pointers and let objects of type B hold a shared or weak pointer to object of type A, depends on ownership you want to have. This way you will have shared pointers in std::vector and memory reallocation would not affect you:
struct A {
A() : state(0) { }
A(int state_arg)
: state{ state_arg } { }
int state;
};
typedef std::shared_ptr<A> APtr;
struct B {
B(int state_arg, const APtr& ptr)
: state{ state_arg }, aptr{ ptr } { }
int state;
APtr aptr;
int ref() const { return aptr->state; }
}
typedef std::shared_ptr<B> BPtr;
using my_type = boost::variant<APtr, BPtr>;
I am reading about the new C++11 syntax for iterating over STL containers.
So far I came across the following example:
std::vector<int> plus;
....
for(int l : plus)
{
std::cout << l;
}
My question is does the above syntax make a copy of the int ?
If so wouldnt this be more efficient ?:
for(int& l : plus)
Semantically, it makes a copy, although for built-in types there may be no efficiency hit, in fact it may even be cheaper to use a copy. But if you have expensive to copy objects, it is a better idea to use const references in the loop.
std::vector<ExpensiveToCopy> v;
for (const auto& i : v)
std::cout << i << std::endl;
You should only really use non-const references if you want to mutate the object.
Yes, if you don't explicitly say you want a reference, you get a copy. With built-in types, its actually more efficient to take a copy - unless you want the semantics of references, of course.
It will call the copy constructor for each element in the vector. If you take it by const reference, it doesn't call any constructors at all. You should use const if you don't plan on mutating the elements. For example:
class Test
{
public:
Test() { std::cout << "Default.\n"; }
~Test() { }
Test(const Test& other) { std::cout << "Copy.\n"; }
Test(Test&& other) { std::cout << "Move.\n"; }
};
int main()
{
std::vector<Test> test;
test.emplace_back(Test());
for (const Test& t : test)
{
}
}
Is there a way in C++ to make an "untyed" function pointer ?
For example:
// pointer to global function
void foo( void (*fptr)() );
// pointer to member
void foo( void (Bar::*fptr)() );
Is there a way I can remove the class on which the member is ? So that I could do something like this:
void foo( void ("any type"::*fptr)(), "same type as for the pointer" &instance );
And then, in foo, I would like to store that pointer in a list, so that I can iterator over the list and call the function/member pointed to, regardless of what class it belongs to. Of course I'd need a list of instances on which to call the function.
Thx.
You can use a template.
template<typename T> void foo( void(T::*)(), T&) { ... }
However, people prefer to go for the function object approach. You can do this dynamically or statically.
void foo(std::function<void()> func) {
// std::bind is used to make this out of a member function
}
template<typename T> void foo(T t = T()) {
t(); // This is the best approach.
}
Edit: Some examples.
void foo(std::function<void()> func) {
std::cout << "In example one ";
func();
}
template<typename T> void foo(T t = T()) {
std::cout << "In example two ";
t();
}
class some_class {
public:
void func() { std::cout << "in ur function!\n"; }
};
int main(void)
{
some_class* ptr = NULL;
struct tempfunctor {
tempfunctor(some_class* newptr)
: ptr(newptr) {}
some_class* ptr;
void operator()() { return ptr->func(); }
};
foo(tempfunctor(ptr)); // Calls example two
foo(std::function<void()>(tempfunctor(ptr))); // Calls example one
foo(std::function<void()>(std::bind(&some_class::func, ptr)); // I'm not that familiar with bind, it looks something similar to this.
std::cin.get();
}
This is the idiom called the function object idiom, used heavily in STL and other high-quality libraries. The compile-time template is cleaner but the std::function can be bound at runtime.
Edit # OP: I didn't quite see your list requirement in there. A std::function<void()> is your best choice here.
The following seems to work fine with g++ and MSVC:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace std;
void foo( boost::function<int()> f )
{
cout << "f() = " << f() << endl;
}
template< class Type >
void foo( int (Type::*f)() const, Type const& o )
{
foo( boost::bind( f, boost::ref( o ) ) );
}
int func1() { return 1; }
struct S { int func2() const { return 2; } };
int main()
{
foo( func1 );
foo( &S::func2, S() );
}
Disclaimer: I seldom use the Boost stuff and I just typed the above without bothering to check the docs, so possibly it could be expressed more cleanly.
Also note that C++0x standard library offers the same functionality.
Cheers & hth.,
No. The bound class is an intrinsic part of the member function pointer type.
You can, however, use a member function pointer to a common baseclass, or a template.
Can you use functors in your list?
http://en.wikipedia.org/wiki/Function_object
Have a look at Fast Delegates: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
This is an easy drop-in library that allows you to delegate pretty much anything and at a very high speed.
template <typename T>
void foo( void (T::*fptr)(), T& instance)
{
// ...
}
I'm not going to play expert here, but I think this will work, if not I would like to know why.
You can't have a pointer like that, but you could have a collection of boost::any, and put heterogeneous pointers (or any kind of functors) into it.
You can't do that, and you shouldn't do that even if you could, because it is against the spirit of the language. Create a base class with "fptr" as a pure virtual member, and inherit all your classes from that class.
Is there a way to make a non-resizeable vector/array of non-reassignable but mutable members? The closest thing I can imagine is using a vector<T *> const copy constructed from a temporary, but since I know at initialization how many of and exactly what I want, I'd much rather have a block of objects than pointers. Is anything like what is shown below possible with std::vector or some more obscure boost, etc., template?
// Struct making vec<A> that cannot be resized or have contents reassigned.
struct B {
vector<A> va_; // <-- unknown modifiers or different template needed here
vector<A> va2_;
// All vector contents initialized on construction.
Foo(size_t n_foo) : va_(n_foo), va2_(5) { }
// Things I'd like allowed: altering contents, const_iterator and read access.
good_actions(size_t idx, int val) {
va_[idx].set(val);
cout << "vector<A> info - " << " size: " << va_.size() << ", max: "
<< va_.max_size() << ", capacity: " << va_.capacity() << ", empty?: "
<< va_.empty() << endl;
if (!va_.empty()) {
cout << "First (old): " << va_[0].get() << ", resetting ..." << endl;
va_[0].set(0);
}
int max = 0;
for (vector<A>::const_iterator i = va_.begin(); i != va_.end(); ++i) {
int n = i->get();
if (n > max) { max = n; }
if (n < 0) { i->set(0); }
}
cout << "Max : " << max << "." << endl;
}
// Everything here should fail at compile.
bad_actions(size_t idx, int val) {
va_[0] = va2_[0];
va_.at(1) = va2_.at(3);
va_.swap(va2_);
va_.erase(va_.begin());
va_.insert(va_.end(), va2_[0]);
va_.resize(1);
va_.clear();
// also: assign, reserve, push, pop, ..
}
};
There is an issue with your requirements. But first let's tackle the fixed size issue, it's called std::tr1::array<class T, size_t N> (if you know the size at compile time).
If you don't know it at compile time, you can still use some proxy class over a vector.
template <class T>
class MyVector
{
public:
explicit MyVector(size_t const n, T const& t = T()): mVector(n,t) {}
// Declare the methods you want here
// and just forward to mVector most of the time ;)
private:
std::vector<T> mVector;
};
However, what is the point of not being assignable if you are mutable ? There is nothing preventing the user to do the heavy work:
class Type
{
public:
int a() const { return a; }
void a(int i) { a = i; }
int b() const { return b; }
void b(int i) { b = i; }
private:
Type& operator=(Type const&);
int a, b;
};
Nothing prevents me from doing:
void assign(Type& lhs, Type const& rhs)
{
lhs.a(rhs.a());
lhs.b(rhs.b());
}
I just want to hit you on the head for complicating my life...
Perhaps could you describe more precisely what you want to do, do you wish to restrict the subset of possible operations on your class (some variables should not be possible to modify, but other could) ?
In this case, you could once again use a Proxy class
class Proxy
{
public:
// WARN: syntax is screwed, but `vector` requires a model
// of the Assignable concept so this operation NEED be defined...
Proxy& operator=(Proxy const& rhs)
{
mType.a = rhs.mType.a;
// mType.b is unchanged
return *this;
}
int a() const { return mType.a(); }
void a(int i) { mType.a(i); }
int b() const { return mType.b(); }
private:
Type mType;
};
There is not much you cannot do with suitable proxies. That's perhaps the most useful pattern I have ever seen.
What you're asking is not really possible.
The only way to prevent something from being assigned is to define the operator = for that type as private. (As an extension of this, since const operator = methods don't make much sense (and are thus uncommon) you can come close to this by only allowing access to const references from your container. But the user can still define a const operator =, and you want mutable objects anyways.)
If you think about it, std::vector::operator [] returns a reference to the value it contains. Using the assignment operator will call operator = for the value. std::vector is completely bypassed here (except for the operator[] call used to get the reference in the first place) so there is no possibility for it (std::vector) to in any way to override the call to the operator = function.
Anything you do to directly access the members of an object in the container is going to have to return a reference to the object, which can then be used to call the object's operator =. So, there is no way a container can prevent objects inside of it from being assigned unless the container implements a proxy for the objects it contains which has a private assignment operator that does nothing and forwards other calls to the "real" object, but does not allow direct access to the real object (though if it made sense to do so, you could return copies of the real object).
Could you create a class which holds a reference to your object, but its constructors are only accessible to its std::vector's friend?
e.g.:
template<typename T>
class MyRef {
firend class std::vector< MyRef<T> >
public:
T& operator->();
[...etc...]
You can achieve what you want by making the std::vector const, and the vector's struct or class data mutable. Your set method would have to be const. Here's an example that works as expected with g++:
#include <vector>
class foo
{
public:
foo () : n_ () {}
void set(int n) const { n_ = n; }
private:
mutable int n_;
};
int main()
{
std::vector<foo> const a(3); // Notice the "const".
std::vector<foo> b(1);
// Executes!
a[0].set(1);
// Failes to compile!
a.swap(b);
}
That way you can't alter the vector in any way but you can modify the mutable data members of the objects held by the vector. Here's how this example compiles:
g++ foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:24: error: passing 'const std::vector<foo, std::allocator<foo> >' as 'this' argument of 'void std::vector<_Tp, _Alloc>::swap(std::vector<_Tp, _Alloc>&) [with _Tp = foo, _Alloc = std::allocator<foo>]' discards qualifiers
The one disadvantage I can think of is that you'll have to be more aware of the const-correctness of your code, but that's not necessarily a disadvantage either.
HTH!
EDIT / Clarification: The goal of this approach is not defeat const completely. Rather, the goal is to demonstrate a means of achieving the requirements set forth in the OP's question using standard C++ and the STL. It is not the ideal solution since it exposes a const method that allows alteration of the internal state visible to the user. Certainly that is a problem with this approach.
I have to pass the address of a member fn taking one argument to the std::for_each. how do i do this?
class A{
void load()
{
vector<int> vt(10,20);
std::for_each(vt.begin(), vt.end(), &A::print);
//It didnt work when i tried mem_fun1(&A::print)
}
void print(int a)
{
cout<<a;
}
};
Thanks
When using std::mem_fun, you have to pass pointer to class as first argument. You can bind it in this case with std::bind1st.
class A
{
public:
void print(int v) {std::cout << v;}
void load()
{
std::vector<int> vt(10, 20);
std::for_each(vt.begin(), vt.end(), std::bind1st(std::mem_fun(&A::print), this));
}
}
What you have in vt are integers not objects of type A. Also, print doesn't manipulate any of the member variables, just make it static:
class A{
void load()
{
vector<int> vt(10,20);
std::for_each(vt.begin(), vt.end(), A::print); // static functions are regular functions
}
static void print(int a)
{
cout<<a;
}
};
I find boost::bind helpful. That way I don't have to remember all the rules associated with std::mem_fun.
#include <boost/bind.hpp>
class A{
void load()
{
vector<int> vt(10,20);
std::for_each(vt.begin(), vt.end(), boost::bind(&A::print,this,_1));
}
void print(int a)
{
cout<<a;
}
};
Though in this particular case, I would prefer the copy to ostream_iterator idiom:
copy(vt.begin(), vt.end(), ostream_iterator<int>(cout, " "));