C++ virtual method problem - c++

I have two structs, in which I'm trying to overwrite a method in the base struct.
The base struct is defined as:
template <class T>
struct compareFunction : public std::binary_function<T,T,bool> {
virtual bool operator() (const T & first, const T & second) {
//This function is always called
return first < second;
}
};
The struct I'm attempting to subclass with is defined as:
template <class Key, class T>
struct valuecomparer : public compareFunction<std::pair<Key,T> > {
std::binary_function<Key, Key,bool> comparer;
bool operator() (const std::pair<Key, T>& x, const std::pair<Key, T> & y) {
//This function is never called
Key tx = x.first;
Key ty = y.first;
if(tx < ty) {
return true;
} else {
return false;
}
}
};
I don't see what I'm doing wrong here, any help would be greatly appreciated.
Ideally, the method in valuecomparer would be called instead of the method in compareFunction.
It is being called basically like this (not necessarily valid syntax,but trying to get idea across):
typedef compareFunction<T> cmpType; //Inside a class definition, T is std::pair<int,double>
valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
cmpType x = compareVar;
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
Apparently after switching the storage from a pure struct to a struct pointer in the class that is using the base struct (and consequently derived struct), everything works. Thanks for all the help :)

According to the code you've posted, in order to have a overridden derived class' function to be called, you MUST call it from a pointer or reference to the base class type, not an object whose type is of the base class itself. So when you create code like this:
cmpType x = compareVar;
x(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
that's always going to call the function definition in the base-class since there is no function that can be used for the polymorphic derived function call. The copy-constructor only copies over the v-table entries and associated members from the base-class. So when you call a method on an object of the base-class type, even if you've created that object from a copy of a derived class, you still end up with the base-class method calls. You would have to-do something like this:
cmpType& x = compareVar;
x(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
Now when the operator() method is called on x, the correct v-table entry is used, that is the overridden version of operator() inside of valuecomparer.

The problem is, from your pseduo-code, you're slicing your comparer:
typedef compareFunction<T> cmpType; //Inside a class definition, T is std::pair<int,double>
valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
cmpType x = compareVar; // *** SLICED HERE ****
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
The easiest solution, given the context, would be the change the declaration of x to be a reference to cmpType, instead of a full-blown instance.
Edit:
Looking closer, the above will not work, at all (you said it was psuedo), but given the intent, looks like you've meant:
valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
compareFunction<pair<int, double> > x = compareVar; // *** SLICED HERE ****
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));

If you're using your valuecomparer for a std::map, then you're missing the fact that an item in the map is defined as std::pair<const Key, Val>. See the const part? :) Add that to your std::pair<>s. If that isn't the problem, report back where and how you actually use those functors.

Related

gmock: How do I pass a pointer of a mock class into another class?

I have to test the following classes with gmock and since I'm pretty new to Gmock Testing in general, I have no idea, where I'm getting these errors from. So I have my Model class in the Model.hpp, which looks like this:
class Model {
public:
Model(double delta_t) : Delta_t(delta_t){};
void add_submodel(std::unique_ptr< Submodel > submodel_ptr); //function adds submodels to private vector below
private:
std::vector<std::unique_ptr< Submodel>> submodel;
protected:
const double Delta_t;
};
The class Model above is using the class Submodel, which is defined like this:
class Submodel {
public:
virtual ~ Submodel() {};
virtual unsigned int get_number_of_states() = 0;
}
I have also defined the corresponding Mock Class for Submodel:
class MockSubmodel : public Submodel {
public:
MOCK_METHOD(unsigned int, get_number_of_states,(),(override));
};
So far so good. Now, I want to test, whether the function model.add_subproblem(std::unique_ptr submodel_ptr) actually adds Submodels to the Model. So therefore I started to define the following test:
TEST(modelTest, Add_Submodel) {
Model::Model model(1);
auto mock1_ptr = std::make_unique<Model::MockSubmodel>();
model.add_subproblem(mock1_ptr);
}
The error I'm getting here is:
error: no viable conversion from 'unique_ptr<Model::MockSubmodel>' to 'unique_ptr<Model::Submodel>'
So my question: What is the right way to pass MockSubmodel as a pointer into add_submodel(), such that it can be recognised as a Submodel? I thought this would happen automatically because of gmock structure?
The add_submodel function takes its std::unique_ptr<Submodel> parameter by value. When you call model.add_subproblem(mock1_ptr);, this would result in mock1_ptr being copied. However, unique_ptr is not copyable.
To fix this, you can remove the variable and directly pass the temporary, as in model.add_subproblem(std::make_unique<Model::MockSubmodel>());. Alternatively, you can move the unique_ptr in, as in model.add_subproblem(std::move(mock1_ptr)); (but you must remember that mock1_ptr will become nullptr after this point).

Using Any class (similar to boost::any) in other templates

I have implemented a pure C++11 Any class (based on this code) which is similar to boost::any and works nicely if used directly.
However I need to use this now as template parameter to assign parameters to variables. Look at this:
class A {
IRecognizer<Any, Any> *_recognizer;
template <typename T1, typename T2>
A(IRecognizer<T1, T2> *x) : _recognizer(x) {
}
}
and
template<typename Symbol, typename ATNInterpreter>
class IRecognizer {
public:
virtual int getState() = 0;
};
Even though I could assign each template parameter to an Any variable, I'm not allowed to assign IRecognizer<T1, T2> to IRecognizer<Any, Any>. Is there a solution for this problem? The error message is:
Cannot initialize a member subobject of type 'IRecognizer<Any, Any> *'
with an lvalue of type 'IRecognizer<Token *, ParserATNSimulator *> *'
The reason I use the Any class is to have a common type that could be assigned with any class reference (similar to Java's Object, but C++ has no common object type from which all other classes derive).
Maybe a different approach is possible here? I'm open for suggestions.
You are trying to convert a IRecognizer<T1, T2> * to a IRecognizer<Any, Any> *. The only allowed pointer conversion is from a derived class pointer to a base class pointer (i.e. Derived* to Base*) or to a more cv-qualified pointer to the same type (i.e. Derived* to Derived const*) or both.
IRecognizer<T1,T2> is not in the same class hierarchy as IRecognizer<Any, Any>. They are two unrelated types. You can add a constructor to convert an IRecognizer<A,B> to an IRecognizer<C,D> if that makes sense, but you can't add a similar thing for pointers.
A pointer to X is not the same as an X.
While you can convert an X into a Y (a IRecognizer<T1,T2> into an IRecognizer<Any,Any>), you cannot convert a pointer to X into a pointer to Y.
You may not want a pointer here. Instead, you might want a value.
However, an interface is not a value.
Java generics are not like C++ templates. A Java generic Bob<Type> is a wrapper around Bob<Object> -- it is actually storing an Object, with a bunch of wrapping casts to-and-from in a layer on top of it.
You can write such wrappers in C++. As an example:
class IRecognizer_base {
public:
virtual int getState() = 0;
};
template<typename Symbol, typename ATNInterpreter>
class IRecognizer:public IRecognizer_base {
};
Now, suppose getState() returned a Symbol:
class IRecognizer_base {
public:
virtual Any getState_() = 0;
};
template<typename Symbol, typename ATNInterpreter>
class IRecognizer:public IRecognizer_base {
public:
inline Symbol getState() {
return getState_(); // whatever conversion required to go from `Any` to `Symbol`
}
};
here, we expose the fact that our objects actually return an Any, but in the interface we cast them over.
If you actually exposed what operations are actually different based on the template types, you can do type erasing tactics that let you store anything that can do those operations instead of a pointer to a specific type.

C++: Store pointer to a member function of an object in another object

I have a class which shall invoke a function specified by the user on certain occasions. Therefore the class has a method void setExternalPostPaintFunction(void(*function)(QPainter&)); that can be used to "register" a function. This function then will be called on that occasion:
class A {
public:
void setExternalPostPaintFunction(void(*function)(QPainter&));
private:
void (*_externalPostPaint)(QPainter&);
bool _externalPostPaintFunctionAssigned;
};
The function pointer is saved in the member variable _externalPostPaint. The implementation of setExternalPostPaintFunction looks like this:
void A::setExternalPostPaintFunction(void(*function)(QPainter&)) {
_externalPostPaint = function;
_externalPostPaintFunctionAssigned = true;
}
Now, this works with normal functions. However, I want to be able to also pass pointers to member functions of objects. From what I know I also have to pass and store the pointer to the object in this case. However, I don't know which type the other object will have. So I guess I'm forced to use templates. I already thought of something like this:
class A {
public:
template <typename T>
void setExternalPostPaintFunction(void(T::*function)(QPainter&), T* object);
private:
void (T::*_externalPostPaint)(QPainter&); //<- This can't work!
bool _externalPostPaintFunctionAssigned;
};
This way I can pass a function pointer and an object pointer to setExternalPostPaintFunction and would probably be able to call the function on the object inside that function. But I'm not able to store it in the variable _externalPostPaint because the type T is only deduced when the function setExternalPostPaintFunction is called, thus I can't have a member variable that depends on this type, since the type of my member variable has to be known when the object is created and apart from that it cannot change, but it would have to in the case when a new function is assigned which possibly could be a member function of an object of different type.
So what is the proper way to do this, or is there any? I'm not super fit with templates and function pointers, so I might have overlooked something.
Anoter option would certainly be to create a functor class with a virtual member function which can be overwritten in a derived class and then pass + store an object pointer of that type instead of the function pointer. But I somehow would prefer my approach if it is somehow possible.
EDIT: SOLUTION
TartanLlama brought me on the right track by suggesting the use of std::function. Here is how I solved it:
class A {
public:
template <typename T>
void setExternalPostPaintFunction(T* object, void(T::*function)(QPainter&)) {
_externalPostPaint = std::bind(function, object, std::placeholders::_1);
_externalPostPaintFunctionAssigned = true;
}
void setExternalPostPaintFunction(std::function<void(QPainter&)> const& function);
private:
std::function<void(QPainter&)> _externalPostPaint;
bool _externalPostPaintFunctionAssigned;
};
As you see, the pointer to the function/member function is stored in an std::function<void(QPainter&)> object now. The advantage is, that an std::function can basically store any callable target. Then there are two overloads: one that can be used for any std::function object that also accepts e.g. a normal function pointer (because the std::function that is expected then is implicitly constructed from that) and one for member functions that have to be called on an object (more for convenience). The latter is implemented as a template. This uses std::bind to create a std::function object of the call of that member function (the user passed) on the object (the user passed).
The overload that takes an std::function is implemented in the source file like this:
void ImageView::setExternalPostPaintFunction(std::function<void(QPainter&)> const& function) {
_externalPostPaint = function;
_externalPostPaintFunctionAssigned = true;
}
Invoking that stored function in the code of class A is now as simple as that:
//canvas is a QPainter instance
if (_externalPostPaintFunctionAssigned) _externalPostPaint(canvas);
The user who wants to register a member function as callback function just has to do the following:
//_imageView is an instance of "A"
//"MainInterface" is the type of "this"
_imageView->setExternalPostPaintFunction(this, &MainInterface::infoPaintFunction);
Or if it's not a member function but just a normal function:
void someFunction(QPainter& painter) {
//do stuff
}
_imageView->setExternalPostPaintFunction(&someFunction);
Or he can explicitly create a std::function object and pass it:
std::function<void(QPainter&)> function = [&](QPainter& painter){ this->infoPaintFunction(painter); };
_imageView->setExternalPostPaintFunction(function);
Works like a charm.
You could use std::function:
class A {
public:
//PostPaintFun can be anything which acts as a function taking a QPainter&
//Could be a lambda, function pointer, functor, etc.
using PostPaintFun = std::function<void(QPainter&)>;
void setExternalPostPaintFunction(PostPaintFun fun);
private:
//Names beginning with an underscore are reserved, don't use them
//Ending with an underscore is fine
PostPaintFun fun_;
bool externalPostPaintFunctionAssigned_;
};
Now you can use member functions like so:
struct B
{
void exec(QPainter&) const;
};
void foo() {
B b;
a.setExternalPostPaintFunction(
[b] (QPainter& p) {b.exec(p);}
);
}
//or inside B
void B::foo() {
a.setExternalPostPaintFunction(
[this] (QPainter&p) {this->exec(p);}
);
}
I have to say I prefer TartanLlama's answer, but here you have something it could work for you.
This might to need some work, but I'm sure you'll get the idea.
struct IFunctionHolder {}; // Used for pointing to any FunctionHolder
typedef IFunctionHolder* functionHolder_ptr; // Alias for IFunctionHolder* .
template<typename Function> // The template for the actual function holders.
struct FunctionHolder: public IFunctionHolder
{
Function function;
};
class A {
public:
template <typename T>
void setExternalPostPaintFunction(void(T::*function)(QPainter&), T* object);
private:
functionHolder_ptr *function_holder; // This memeber can hold eny instantiation of template<> FunctionHolder.
// Instantiate this member wen calling setExternalPostPaintFunction
bool _externalPostPaintFunctionAssigned;
};
You could have some code like this:
A some_a;
void some_a.setExternalPostPaintFunction(&SomeInstance::some_fnunction); // Here take place the instantiation of FunctionHolder.
some_a.function_holder.function(some_painter);

Call method only once for EACH object of the class NOT STATIC

I wrote a class where the constructor is private.
I need to assign the given value to the private members ONLY ONCE
in the method construct(int a).
It should be something like a constructor but not a constructor !
Every time this construct(int a) is called after the first time,
I do not need to reassign anything to that specific OBJECT.
How to achieve that without any booleans?
I thought of boost::call_once but it calls construct(int a) once for ENTIRE CLASS! and I need to call this function ONCE for EACH OBJECT.
just like ctor! Any ideas?
UPDATE 1:
The Constructor is private. But the class has some members those values can be assigned from the outside but only ONCE
I am trying to achieve some automatisation for checking if a function was called or not already without using bool wasCalled or something like that.
UPDATE 2:
LT::Pointer lut = LT::New();
std::vector<double> points;
....
lut->construct(points);
The second time
lut->construct(points);
is called - error should be given, or just somehow make it impossible.
Direct Answer:
You can devise a wrapper that applies "assign-once" semantics to the wrapped object.
However, you can not make the compiler detect that a value is being set for the second time at compile time, so you should be prepared to make it assert/throw at runtime.
Background/look around
As others have said, this smells very much like a design flaw. Why can't you have the New operation forward constructor parameters (a-la make_shared, make_unique?):
template <typename T, typename... Args>
SmartPointer<T> genericNew(Args&&... args) {
return SmartPointer<T>(new T(std::forward<Args>(args)...));
}
Of course, there could be specialized factory methods that even know how to set private properties after construction. Make the factory methods friends, to preven others from using the hidden property (setters) after creation by the factory:
struct X {
int a;
X(int i) : a(i) {}
typedef SmartPointer<X> Ptr;
static Ptr New(int a, int init_only) {
Ptr p(new X(a));
p->init_only = init_only;
return p;
}
private:
int init_only;
};
(here I opted to make the New factory method a static member, so it's implicitly a friend)

C++ One std::vector containing template class of multiple types

I need to store multiple types of a template class in a single vector.
Eg, for:
template <typename T>
class templateClass{
bool someFunction();
};
I need one vector that will store all of:
templateClass<int> t1;
templateClass<char> t2;
templateClass<std::string> t3;
etc
As far as I know this is not possible, if it is could someone say how?
If it isn't possible could someone explain how to make the following work?
As a work around I tried to use a base, non template class and inherit the template class from it.
class templateInterface{
virtual bool someFunction() = 0;
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction();
};
I then created a vector to store the base "templateInterface" class:
std::vector<templateInterface> v;
templateClass<int> t;
v.push_back(t);
This produced the following error:
error: cannot allocate an object of abstract type 'templateInterface'
note: because the following virtual functions are pure within 'templateInterface'
note: virtual bool templateInterface::someFunction()
To fix this error I made the function in templateInterface not a pure virtual by providing a function body, this compiled but when calling the function the overide is not used, but instead the body in the virtual function.
Eg:
class templateInterface{
virtual bool someFunction() {return true;}
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction() {return false;}
};
std::vector<templateInterface> v;
templateClass<int> i;
v.push_back(i);
v[0].someFunction(); //This returns true, and does not use the code in the 'templateClass' function body
Is there any way to fix this so that the overridden function is used, or is there another workaround to store multiple template types in a single vector?
Why your code doesn't work:
Calling a virtual function on a value doesn't use polymorphism. It calls the function which is defined for the type of this exact symbol as seen by the compiler, not the runtime type. When you insert sub types into a vector of the base type, your values will be converted into the base type ("type slicing"), which is not what you want. Calling functions on them will now call the function as defined for the base type, since not it is of that type.
How to fix this?
The same problem can be reproduced with this code snippet:
templateInterface x = templateClass<int>(); // Type slicing takes place!
x.someFunction(); // -> templateInterface::someFunction() is called!
Polymorphism only works on a pointer or reference type. It will then use the runtime type of the object behind the pointer / reference to decide which implementation to call (by using it's vtable).
Converting pointers is totally "safe" with regard to type slicing. Your actual values won't be converted at all and polymorphism will work as expected.
Example, analogous to the code snippet above:
templateInterface *x = new templateClass<int>(); // No type slicing takes place
x->someFunction(); // -> templateClass<int>::someFunction() is called!
delete x; // Don't forget to destroy your objects.
What about vectors?
So you have to adopt these changes in your code. You can simply store pointers to actual types in the vector, instead of storing the values directly.
When working with pointers you also have to care about deleting your allocated objects. For this you can use smart pointers which care about deletion automatically. unique_ptr is one such smart pointer type. It deletes the pointee whenever it goes out of scope ("unique ownership" - the scope being the owner). Assuming the lifetime of your objects is bound to the scope this is what you should use:
std::vector<std::unique_ptr<templateInterface>> v;
templateClass<int> *i = new templateClass<int>(); // create new object
v.push_back(std::unique_ptr<templateInterface>(i)); // put it in the vector
v.emplace_back(new templateClass<int>()); // "direct" alternative
Then, call a virtual function on one of these elements with the following syntax:
v[0]->someFunction();
Make sure you make all functions virtual which should be possible to be overridden by subclasses. Otherwise their overridden version will not be called. But since you already introduced an "interface", I'm sure you are working with abstract functions.
Alternative approaches:
Alternative ways to do what you want is to use a variant type in the vector. There are some implementations of variant types, the Boost.Variant being a very popular one. This approach is especially nice if you don't have a type hierarchy (for example when you store primitive types). You would then use a vector type like std::vector<boost::variant<int, char, bool>>
Polymorphism only works through pointers or references. You'll
need the non-template base. Beyond that, you'll need to decide
where the actual objects in container will live. If they're all
static objects (with sufficient lifetime), just using
a std::vector<TemplateInterface*>, and inserting with
v.push_back(&t1);, etc., should do the trick. Otherwise,
you'll probably want to support cloning, and keep clones in the
vector: preferably with Boost pointer containers, but
std::shared_ptr can be used as well.
The solutions given so far are fine though be aware that in case you were returning the template type other than bool in your example , none of these would help as the vtable slots would not be able to be measured before hand. There are actually limits , from a design point of view , for using a template oriented polymorphic solution.
Solution nr. 1
This solution inspired by Sean Parent's C++ Seasoning talk. I highly recommend to check it out on youtube. My solution simplified a bit and the key is to store object in method itself.
One method only
Create a class that will invoke method of stored object.
struct object {
template <class T>
object(T t)
: someFunction([t = std::move(t)]() { return t.someFunction(); })
{ }
std::function<bool()> someFunction;
};
Then use it like this
std::vector<object> v;
// Add classes that has 'bool someFunction()' method
v.emplace_back(someClass());
v.emplace_back(someOtherClass());
// Test our vector
for (auto& x : v)
std::cout << x.someFunction() << std::endl;
Several methods
For several methods use shared pointer to share object between methods
struct object {
template <class T>
object(T&& t) {
auto ptr = std::make_shared<std::remove_reference_t<T>>(std::forward<T>(t));
someFunction = [ptr]() { return ptr->someFunction(); };
someOtherFunction = [ptr](int x) { ptr->someOtherFunction(x); };
}
std::function<bool()> someFunction;
std::function<void(int)> someOtherFunction;
};
Other types
Primitive types (such as int, float, const char*) or classes (std::string etc.) may be wrapped in the same way as object class do but behave differently. For example:
struct otherType {
template <class T>
otherType(T t)
: someFunction([t = std::move(t)]() {
// Return something different
return true;
})
{ }
std::function<bool()> someFunction;
};
So now it is possible to add types that does not have someFunction method.
v.emplace_back(otherType(17)); // Adding an int
v.emplace_back(otherType("test")); // A string
Solution nr. 2
After some thoughts what we basically done in first solution is created array of callable functions. So why not just do the following instead.
// Example class with method we want to put in array
struct myclass {
void draw() const {
std::cout << "myclass" << std::endl;
}
};
// All other type's behaviour
template <class T>
void draw(const T& x) {
std::cout << typeid(T).name() << ": " << x << std::endl;
}
int main()
{
myclass x;
int y = 17;
std::vector<std::function<void()>> v;
v.emplace_back(std::bind(&myclass::draw, &x));
v.emplace_back(std::bind(draw<int>, y));
for (auto& fn : v)
fn();
}
Conclusion
Solution nr. 1 is definitely an interesting method that does not require inheritance nor virtual functions. And can be used to other stuff where you need to store a template argument to be used later.
Solution nr. 2, on the other hand, is simpler, more flexible and probably a better choice here.
If you're looking at a container to store multiple types, then you should explore boost variant from the popular boost library.