Return different types from c++ functions - c++

Ok, so I am struggling with the following:
I have a class (A), which holds a vector<B> (a vector for Qt) of some other classes (B). The class B has a property, let's say p and also has a name.
For one case, I would like to get a listing of the B objects that are to be found in class A which have the p property set, and for another case I would like to get a list of the names of the B objects that have the property set.
And most of all, I would like to have these two functions to be called the same :)
So, something like:
class A
{
public:
QVector<B*> B_s_with_p() { ... }
QStringList B_s_with_p() { ... }
};
but I don't want to have a helper parameter to overload the methods (yes, that would be easy), and the closest I have got is a method with a different name ... which works, but it's ugly. Templates don't seem to work either.
Is there a way using todays' C++ to achieve it?

A cheat would be to use a reference to QVector<B*> or QStringList as an argument instead of a return type. That way you can overload B_s_with_p as normal. I guess you don't consider that a valid option.

Only the signature is used to overload methods. That means the return type can't be use to overload.
You have to use different methods names or manage your return value with a parameter :
class A
{
public:
void B_s_with_p(QVector<B*>&);
void B_s_with_p(QStringList&);
};
B_s_with_p() could use a template type as parameter.

Why do you think that having two different names for two different sets of functionality is ugly? That's exactly what you should be doing to delineate the different return types here.
Another alternative is to have just the function that returns an object, and then create a names_of method that you pass the list of B objects and it returns the list of names.

Check your design .. Overloaded functions are one which have similar funcionality but differnt argument types .. So check why you want to
I would like to have these two functions to be called the same
refer to :What is the use/advantage of function overloading?
The benefit of overloading is consistency in the naming of functions which perform the same task, just with different parameters.

Related

map to a function pointer with different number of arguments and varying datatypes

In my code, I have several class, each with different methods. For example:
class A {
public:
int sum(int a, int b);
bool isScalable(double d);
}
class B {
public:
std:string ownerName();
}
My aim is to create a map of all the function names as below
std::map<std::string, FnPtr> myMap;
// Add the newly implemented function to this map
myMap["sum"] = &A::sum;
myMap["isScalable"] = &A::isScalable;
myMap["myMap"] = &B::myMap;
The issue is I am not aware how I can define FnPtr. Can you please help me out.
As comments suggest, it is unlikely you really want to do this.
Assuming that you do, however - perhaps you should reconsider whether C++ is the right language for the task. Another language which has better runtime reflection facility might be more appropriate; perhaps an interpreted language like Python or Perl. Those are typically much more convenient when you need to look up class methods by name at runtime.
If it has to be C++, then perhaps you should relax the class structure somewhat. Use a single class for both A's and B's (lets call it MyCommonObj); and have the class hold a map of strings to function pointers. As for these functions' signatures - It's probably a good idea not to make the member functions, but freestanding ones. In that case, perhaps your function pointer type would be:
using generic_function = std::any (*)(std::vector<std::any>);
That's pretty generic - for storage and for invocation. If you have this map, you can easily look up your function name and pass the arguments. However, you might need to also keep additional information about what type your arguments should be, otherwise you'll always be passing strings. ... which is also an option, I suppose:
using generic_function = std::any (*)(std::vector<std::string>);
Now if the A and B members in your example are really non-static like you listed them, i.e. they use instance fields, then these generic functions must also always take a reference or pointer to an instance of MyCommonObj:
using generic_function = std::any (*)(MyCommonObj&, std::vector<std::string>);
Finally, note that code using this type, and run-time lookup of function names etc - will not be very performant.
If you're not using C++17 and don't have access to std::any, you can either:
Use boost::any from the Boost libraries.
Use an any-emulator library (which exist on GitHub)
Use a union of all the types you actually use, e.g. union {int i; double d;} - but then you'll need to protect yourself against passing values of the wrong type.

Sharing function between classes

I have three classes which each store their own array of double values. To populate the arrays I use a fairly complex function, lets say foo(), which takes in several parameters and calculates the appropriate values for the array.
Each of my three classes uses the same function with only minor adjustments (i.e. the input parameters vary slightly). Each of the classes is actually quite similar although they each perform separate logic when retrieving the values of the array.
So I am wondering how should I 'share' the function so that all classes can use it, without having to duplicate the code?
I was thinking of creating a base class which contained the function foo() and a virtual get() method. My three classes could then inherit this base class. Alternatively, I was also thinking perhaps a global function was the way to go? maybe putting the function into a namespace?
If the classes have nothing in common besides this foo() function, it is silly to put it in a base class; make it a free function instead. C++ is not Java.
Declaring of a function in base class sounds the most appropriate solution. Not sure if you need virtual "get" though, instead just declare the array in the base class and provide access method(s) for descendants.
More complex part is "the input parameters vary slightly". If parameters differ by type only then you may write a template function. If difference is more significant than the only solution I see is splitting main function into several logic blocks and using these blocks in descendant classes to perform final result.
If your classes are quite similar, you could create a template class with three different implementations that has the function foo<T>()
Implement that function in base class. If these classes are similar as you say, they should be derived from one base class anyway! If there are several functions like foo(), it might be reasonable in some cases to combine them into another class which is utilized by/with your classes.
If the underlying data of the class is the same (Array of doubles), considering using a single class and overloading the constructor, or just use 3 different functions:
void PopulateFromString(const string&)
void PopulateFromXml(...)
void PopulateFromInteger(...)
If the data or the behavior is different in each class type, then your solution of base class is good.
You can also define a function in the same namespace as your classes as utility function, if it has nothing to do with specific class behavior (Polymorphism). Bjarne StroupStroup recommends this method by the way.
For the purpose of this answer, I am assuming the classes you have are not common in any other outwards way; they may load the same data, but they are providing different interfaces.
There are two possible situations here, and you haven't told us which one it is. It could be more like
void foo(double* arr, size_t size) {
// Some specific code (that probably just does some preparation)
// Lots of generic code
// ...
// Some more specific code (cleanup?)
}
or something similar to
void foo(double* arr, size_t size) {
// generic_code();
// ...
// specific_code();
// generic_code();
// ...
}
In the first case, the generic code may very well be easy to put into a separate function, and then making a base class doesn't make much sense: you'll probably be inheriting from it privately, and you should prefer composition over private inheritance unless you have a good reason to. You could put the new function in its own class if it benefits from it, but it's not strictly necessary. Whether you put it in a namespace or not depends on how you're organising your code.
The second case is trickier, and in that case I would advise polymorphism. However, you don't seem to need runtime polymorphism for this, and so you could just as well do it compile-time. Using the fact that this is C++, you can use CRTP:
template<typename IMPL>
class MyBase {
void foo(double* arr, size_t size) {
// generic code
// ...
double importantResult = IMPL::DoALittleWork(/* args */);
// more generic code
// ...
}
};
class Derived : MyBase<Derived> {
static double DoALittleWork(/* params */) {
// My specific stuff
return result;
}
};
This gives you the benefit of code organisation and saves you some virtual functions. On the other hand, it does make it slightly less clear what functions need to be implemented (although the error messages are not that bad).
I would only go with the second route if making a new function (possibly within a new class) would clearly be uglier. If you're parsing different formats as Andrey says, then having a parser object (that would be polymorphic) passed in would be even nicer as it would allow you to mock things with less trouble, but you haven't given enough details to say for sure.

How to instantiate objects whose constructor requires parameters from a string holding the class name?

Is there a way to instantiate objects from a string holding their class name?
I got a problem basically the same with the above question. But I need to instantiate a class with some parameters. different class constructor name may require different number of variables and the type of each variable may differ either. And because the class contains constant variables so you could not new it with new T() and then set the parameter to the correct value. the "class name"-"constructor" map seems not suitable for my needs.
Any alternatives?
I'm going to preface this by saying, maybe C++ isn't the right language for whatever you're trying to accomplish. The more you try to control your program via external data, the closer you get to full on scripting. And there are lots of more powerful options when that is your goal.
That said, sure, it is possible, although not as easily. Two ways come immediately to mind. The first is to require all applicable types to have a constructor that accepts a std::string. This constructor will be responsible for its own parsing.
template<typename T> Base * createInstance(const std::string& s) { return new T(s); }
typedef std::map<std::string, Base*(*)(const std::string&)> map_type;
//...and similar changes as needed
If you don't want to change your type definitions, or this is otherwise unacceptable [perhaps your types already have such a constructor?], get rid of the templated createInstance method, and provide individual versions for each type you are interested in. This function does the parsing, and calls the appropriate constructor.
map["derivedA"] = createDerivedA;
map["derivedB"] = createDerivedB;
A third option might be possible using variadic templates [or boost-esque variadic-like templates] that would bring you back to the original simplicity.
template<typename T, typename... Args>
Base* create(std::string) {
//somehow pass the string to a generic function that packs the arguments into a tuple
//then somehow unpack that tuple and pass the bits to the constructor
}
map["derivedA"] = create<derivedA, int, double, std::string>;
However, I have no idea how to pull that off, or even if it is possible.
You could use a factory design patten. pass your string to the factory class and then let it decode your string choosing the correct version of the constructor and class to call. it would then pass back an instance of the correct class for the rest of your code to use.
Here's some info factory design pattern

runtime type comparison

I need to find the type of object pointed by pointer.
Code is as below.
//pWindow is pointer to either base Window object or derived Window objects like //Window_Derived.
const char* windowName = typeid(*pWindow).name();
if(strcmp(windowName, typeid(Window).name()) == 0)
{
// ...
}
else if(strcmp(windowName, typeid(Window_Derived).name()) == 0)
{
// ...
}
As i can't use switch statement for comparing string, i am forced to use if else chain.
But as the number of window types i have is high, this if else chain is becoming too lengthy.
Can we check the window type using switch or an easier method ?
EDIT: Am working in a logger module. I thought, logger should not call derived class virtual function for logging purpose. It should do on its own. So i dropped virtual function approach.
First of all use a higher level construct for strings like std::string.
Second, if you need to check the type of the window your design is wrong.
Use the Liskov substitution principle to design correctly.
It basically means that any of the derived Window objects can be replaced with it's super class.
This can only happen if both share the same interface and the derived classes don't violate the contract provided by the base class.
If you need some mechanism to apply behavior dynamically use the Visitor Pattern
Here are the things to do in order of preference:
Add a new virtual method to the base class and simply call it. Then put a virtual method of the same name in each derived class that implements the corresponding else if clause inside it. This is the preferred option as your current strategy is a widely recognized symptom of poor design, and this is the suggested remedy.
Use a ::std::map< ::std::string, void (*)(Window *pWindow)>. This will allow you to look up the function to call in a map, which is much faster and easier to add to. This will also require you to split each else if clause into its own function.
Use a ::std::map< ::std::string, int>. This will let you look up an integer for the corresponding string and then you can switch on the integer.
There are other refactoring strategies to use that more closely resemble option 1 here. For example,if you can't add a method to the Window class, you can create an interface class that has the needed method. Then you can make a function that uses dynamic_cast to figure out if the object implements the interface class and call the method in that case, and then handle the few remaining cases with your else if construct.
Create a dictionary (set/hashmap) with the strings as keys and the behaviour as value.
Using behaviour as values can be done in two ways:
Encapsulate each behaviour in it's
own class that inherit from an
interface with"DoAction" method that
execute the behavior
Use function pointers
Update:
I found this article that might be what you're looking for:
http://www.dreamincode.net/forums/topic/38412-the-command-pattern-c/
You might try putting all your typeid(...).name() values in a map, then doing a find() in the map. You could map to an int that can be used in a switch statement, or to a function pointer. Better yet, you might look again at getting a virtual function inside each of the types that does what you need.
What you ask for is possible, it's also unlikely to be a good solution to your problem.
Effectively the if/else if/else chain is ugly, the first solution that comes to mind will therefore to use a construct that will lift this, an associative container comes to mind and the default one is obviously std::unordered_map.
Thinking on the type of this container, you will realize that you need to use the typename as the key and associate it to a functor object...
However there are much more elegant constructs for this. The first of all will be of course the use of a virtual method.
class Base
{
public:
void execute() const { this->executeImpl(); }
private:
virtual void executeImpl() const { /* default impl */ }
};
class Derived: public Base
{
virtual void executeImpl() const { /* another impl */ }
};
It's the OO way of dealing with this type of requirement.
Finally, if you find yourself willing to add many different operations on your hierarchy, I will suggest the use of a well-known design pattern: Visitor. There is a variation called Acyclic Visitor which helps dealing with dependencies.

Derived Functor with any return type and any parameters

I have a class that uses functors as units of work. It accepts a reference to a functor in its Run() method. To allow this class to operate on any functor, all these functors must derive from my base functor class which looks like this:
class baseFunctor{
public:
virtual void operator()()=0;
virtual baseFunctor Clone()=0;
};
This works, however obviously it restricts these functors to having an operator method that returns void and accepts no parameters. I need to be able to accept a functor in my class that can take any type of parameters and return anything. Its apparently do-able but I can't seem to find a way to do it. I have considered using templates, multiple inheritance, but I keep getting thwarted by the fact that the class that needs to run this functor must be able to accept any type, so will accept the base class type, and so will not know the actual type of the functor.
Any suggestions of what avenue to look at would be appreciated.
How will the class that calls the functor know what parameters to provide and what to do with the return value, if any?
So, if I'm reading this right, you have a "Visitor pattern." It might be a good thing for you to look up.
Someone needs to know what type the functor is to give it arguments. Often with functors, the arguments are assigned to fields of the derived class, and operator() will operate on those fields. That is, the dumb method that calls the functor and doesn't know anything about it is given the closure (method plus arguments all in one class) by someone more knowledgeable.
If you do want generic functors that take multiple arguments in the operator(), templating will get you partway there, but you'll need one per arity.
I agree with Neil. Your main class has to know what parameters to pass and what return value to expect from these functors. Can you just type-cast your "functor" to an appropriate class that supports the function with the necessary arguments and return value?
class baseFunctor
{
};
class functor1x2: public baseFunctor
{
public:
virtual void* execute(void*, void*);
}
class MainClass
{
public:
void Execute(baseFunctor* ipFunctor)
{
functor1x2* lpFunctor1x2 = dynamic_cast<functor1x2*>(ipFunctor);
if(lpFunctor1x2)
{
lpFunctor1x2->execute(NULL, NULL);
}
}
}
I'm not sure what could be accomplished with this approach that couldn't more easily be accomplished with the Visitor pattern, as Drew noted.
If you are open to using the Boost library (www.boost.org), you might find Boot.Bind and Boost.Function of particular interest. I have used them in the past to achieve something very much along the lines of what you are discussing.
If you use Boost.Bind, you can perform currying on the functors to account for differences between the number of arguments the functor expects and the number of arguments the Run method expects (i.e., zero). The code that creates the functor would have to bind any arguments to specific values and thus create a zero-argument functor that can be passed to Run().
MV
Why'd you want to return the functor? Are you storing some state as well? Some more detail will be much appreciated since it is not very clear what exactly you want to do.
If you plan to use inheritance, do look up Covariant Return Types (and the Virtual Constructor idiom).
Now, for the meat of the problem: the problem is really not with passing in a functor but with functor application. You may want to take a look at boost::lambda and boost::parameter as well.
I think you want an ellipsis argument, like varargs for C++.
Perhaps std::tr1::function is interesting for you?