I have the following template structure:
template <typename scalar_type>
struct postc_params{
scalar_type delta;
unsigned int time_horizon;
matrix_math::matrix<scalar_type> dynamics;
boost::shared_ptr<continuous_set> invariant_set_ptr;
boost::shared_ptr<continuous_set> input_set_ptr;
boost::shared_ptr<continuous_set> initial_set_ptr;
};
Now, I have a templated class with a private member of the above structure type
template <typename scalar_type>
class A{
....
private:
....
postc_params<scalar_type> my_postc;
};
Inside a member function definition of class A, I have the following line of code:
my_postc.initial_set_ptr = my_postc.initial_set_ptr->transform(some_obj);
transform function returns a pointer of type
boost::shared_ptr<continuous_set>
With this code, I have the following error:
passing 'const boost::shared_ptr' as 'this' argument of 'boost::shared_ptr< >& boost::shared_ptr< >::operator=
(const boost::shared_ptr&) [with Y = const continuous::continuous_set, T = continuous::continuous_set]' discards qualifiers
Can anyone help me out with the cause?
Is the member function in A const?
If I am reading your code right, you are trying to change a member of a class from a const member function which is not allowed. Either remove the const from the member function or make the member mutable.
So,
mutable postc_params<scalar_type> my_postc;
However, I would take care with this method. Maybe reevaluate why the method that is changing my_postc is const. Either it should not be const or it should not be changing my_postc.
you are trying to assign to a const pointer as per the error message: "passing 'const boost::shared_ptr' as 'this' argument"
the member function you mention is surely const hence the error
you should rather reconsider your design than throw mutable here and there in your code.
Related
I have a class of items and a function that returns it's size.
I have the operator == which gets 2 const parameters of the class type and return the result of item1.size() == item2.size (). size function is non-parametres func and need only hidden this parameter.
The problem is when I try to use size on const reference of classes, it's give me an error:
'function' : cannot convert 'this' pointer from 'type1' to 'type2'
The compiler could not convert the this pointer from type1to type2.
This error can be caused by invoking a non-const member function on a const object. Possible resolutions:
Remove the const from the object declaration.
Add const to the member function.
The piece of code as it is on my problem:
bool operator==(const CardDeck& deck1, const CardDeck& deck2){
if (deck1.size() != deck2.size()) {
return false;
}
//...
}
The error:
'unsigned int CardDeck::size(void)' : cannot convert 'this' pointer from 'const CardDeck' to 'Cardeck&'
If I want that size will get the object as const, I must make it friend and pass the object as const refference or is there a way to tell size get the class type this as constant ???
Thanks for helping.
Most likely you forgot to qualify the size member function as const: size_t size() const { return /* compute/return size */; }
The alternative is that you really did typo CardDeck as Cardeck somewhere (the spelling from your error message).
What is the reason why pointers to member functions, can't point to const member functions?
struct A {
void g() {};
void f() const {}
};
Later in code:
void (A::* fun)() = &A::f;
This code produces:
error: cannot convert ‘void (A::*)()const’ to ‘void (A::*)()’ in initialization
Of course it compiles with &A::g instead of &A::f.
In opposite situation:
void (A::* fun)() const = &A::g;
The error is:
error: cannot convert ‘void (A::*)()’ to ‘void (A::*)()const’ in initialization
The second case is rather clear. const pointer isn't expected to modify the object so it can't hold the function which does it. But why it's not possible to assign const member function to non-const member function as in the first case?
It looks like the rule for normal pointers where casting const to non-const would allow to modify the value, but I don't see the point here, where const-correctness is checked in function definition, before such assignment.
What is the reason why pointers to member functions, can't point to const member functions?
Because the const modifier is part of the function signature. Once you declare a function pointer, that function pointer can only be used to assign pointers to function that have the same function signature.
Non-static member functions have an extra hidden this parameter. Given the existence of that that extra hidden parameter, a non-static void A::f() const; behaves much like void A__f(const A *__this), and the behaviour you see for member functions models the behaviour for non-member functions.
void f(void *);
void (*pf)(const void *) = f; // also an error
As for whether it could break on any implementation, I suppose in theory, an implementation is permitted to read a void * parameter from a different register than a const void * parameter, and if so, the result of the conversion (were it valid) could not be used to call f properly. I have no idea why any implementor would make such a decision, and I don't know of any real implementation that does so, but it's one allowed by the standard.
I am working with a member function that just sets the object's internal orientation to the values given in the argument:
void A::SetOrientation(float a[3]);
In another class, I have the following:
class B
{
public:
RestoreStateTo(A* const o_pA) const
private:
float d_orientation[3];
};
void
B::RestoreStateTo(A* const o_pA) const
{
o_pA->SetOrientation(d_orientation);
}
I get the following compiler error (with Visual Studio 2010):
error C2664: 'void A::SetOrientation(float [])' : cannot convert parameter 1 from 'const float [3]' to 'float []'
I found that I can avoid the issue with o_pA->SetOrientation(const_cast<float *>(d_orientation));, but I'd like to get a better grasp of what is going on.
I would appreciate an explanation as to why the array argument is converted to a const array as well as suggest the right approach to dealing with the error?
Because the prototype of your function void B::RestoreStateTo(A* const o_pA) const says you will not modify any member of B.
Since d_orientation is an attribute of B, it is const in this function.
Your SetOrientation function should take in a const,
void A::SetOrientation(const float a[3]);
Otherwise, it's possible that A::SetOrientation will modify the array you pass in. Because you have "B::RestoreStateTo(A* const o_pA) const", it means that the compiler won't let you pass a pointer to B::d_orientation as a non-const input, because A::SetOrientation has no guarantee not to modify it.
You have declared a const member function, and therefore all the members of this will be treated as const inside that function. So it shouldn't be surprising that d_orientation is treated as const.
It's the same principle that makes this code illegal:
const B* p = ...;
p->d_orientation[0] = 0.0f; // error, assigning member of `const` object
I am trying to create a custom sort for a vector of class pointers by using a sort predicate:
struct sort_by_airtime
{
inline bool operator() (const Network *n1, const Network *n2)
{
return (n1->airtime() < n2->airtime());
}
};
For each network, we sort by a float returned by airtime().
Now, I try to use this as follows:
std::vector<Network *> Simulator::sort_networks(std::vector<Network *> netlist, bool sort_airtime) {
std::vector<Network *> new_netlist = netlist;
if(sort_airtime) {
sort(new_netlist.begin(), new_netlist.end(), sort_by_airtime());
}
}
However, I get a lot of errors like this:
In file included from Simulator.cpp:7:
Simulator.h: In member function ‘bool Simulator::sort_by_airtime::operator()(const Network*, const Network*)’:
Simulator.h:48: error: passing ‘const Network’ as ‘this’ argument of ‘virtual float Network::airtime()’ discards qualifiers
Simulator.h:48: error: passing ‘const Network’ as ‘this’ argument of ‘virtual float Network::airtime()’ discards qualifiers
Am I not specifying the argument passed to the predicate properly? airtime() is implemented by classes that inherit the Network class.
The compiler is warning you that Network::airtime() is ignoring the const qualifiers on n1 and n2.
The solution would be to create a "const-correct" version of Network::airtime() (assuming it actually doesn't modify anything).
See this answer for an example.
Your member function should be declared as const member function as:
virtual float Network::airtime() const
^^^^^ //this makes the function const
because the pointers which you're using in operator() are pointing to const objects of type Network.
Network::airtime() is not const, and so can't be called via the const Network* you have in sort_by_airtime.
If possible, the best solution is to make airtime() const; otherwise change the sort_by_airtime arguments to Network*.
I was wondering what the syntax was for a pointer to a constant member variable.
I know a pointer to a non-const member function and a pointer to a const member function are expressly different types, ie, the following are two distinct types:
typedef void (Foo::*Bar)(void);
typedef void (Foo::*ConstBar)(void) const;
I was wondering if the same could be said of pointers to non-const and const member variables, ie are the following two distinct types as well, and if so, what is the syntax of the latter:
typedef int (Foo::*var);
typedef int (Foo::*constVar) const; // Not the correct syntax.
Thanks.
The type of the pointer-to-member needs to match the type of the member:
typedef int (Foo::*var); // pointer to a data member of type 'int'
typedef const int (Foo::*cvar); // pointer to a data member of type 'const int'
The const-qualification of a member function is a part of its type, just like the return type is a part of its type.
Just to make it funnier:
typedef const int (Foo::*(Foo::*ConstBar)(void) const);
ConstBar is a pointer to a const-member function taking no arguments and returning a pointer to a const-member of type int.
A general tip of how to remember the syntax in your question: you just write it the way you would define the member of the class
void name(void) const; // const function
const int name; // const member
And then replace name by (Foo::*name), resulting in:
void (Foo::*name)(void) const; // pointer to const function
const int (Foo::*name); // pointer to const member