Parameter of type "has << operator" - c++

I need to draw my object on an out stream, which is usually cout.
But I also want the user to be able to input any stream that has << operator (such as QTextStream), so it doesn't have to be cout every time.
What's the easiest way to define such parameter?
So this is what I'd like to have, something compilable tho:
virtual void draw(GeneralOutStream out = std::cout)
{
out << m_name << std::endl;
}
I know I could use templates, (which is what I'm doing atm.) but I was hoping there would be a solution that doesn't require templates.
However, the template solution works fine, so basically I'm just curious.

I can think of Four approaches.
First, take std::ostream as your GeneralOutStream, and assume everyone inherits from it. Maybe write some stuff that wraps a QTextStream up in a way that makes it a std::ostream.
Second, write a template method that takes GeneralOutStream&& out and operates on it. This requires exposing your implementation in your header. I'd recommend this one. Quite strongly, but it does mean that virtual ends up being pretty useless.
Third, write a type erasure GeneralOutStream that exposes the parts of the general out stream you want to interact with within your class with a template constructor that stores the passed in generic type in a pImpl with virtual methods, then use that type within the implementation of your object. This has runtime overhead and is quite tricky to write, and resembles the pattern of std::function -- except GeneralOutStream has to handle being able to write an entire myriad of types!
If I was to write #3, GeneralOutStream would be a template that takes a sequence of types the GeneralOutStream is supposed to handle, then does some metaprogramming to expose exactly those overloads to <<. This gets really tricky, because you need to replicate overload resolution manually.
Forth, create an enumeration of "GeneralOutStream" types that you want to support. Use double-dispatch techniques to ferry references to instances of those types through a virtual method call, unbundling them at the other side and calling your implentation template methods, requiring that the implementing class handle the entire enumeration. This one is slightly less tricky to implement than #3, limits what types you can pass to the draw method, but allows full access to the type in the implementation class.

You want a solution any stream (derived from std::ostream) or for any object that has << operator?
In the first case, you can pass a reference to the stream object:
virtual void draw(std::ostream& out = cout) {
out << m_name << std::endl;
}
Passing a copy won't compile.
In the second case, the main problem is the interface, since it looks you want to define that function as virtual member. If is not the case and you still want a solution for any object (not necessary standard ostream, but any with operator << defined), you'll have to use templates.

Related

Static CRTP class without knowing derived type?

Given the following, working code.
#include <iostream>
template<class Detail>
class AbstractLogger
{
public:
static void log(const char* str) {
Detail::log_detailled(str);
}
};
class Logger : public AbstractLogger<Logger>
{
public:
static void log_detailled(const char* str) {
std::cerr << str << std::endl;
}
};
int main(void)
{
AbstractLogger<Logger>::log("main function running!");
return 0;
}
Now, I want to put AbstractLogger into a library, and let the library user define his own logger, like the Logger class here. This has one drawback: AbstractLogger<Logger> can not be used inside the library, since the library can not know Logger.
Notes:
Please no virtual functions or questions why not. Also, I am aware of the similar problem that "static virtual" members are invalid. Maybe, there is a workaround in CRTP :)
C++11 will be interesting, however, I need "usual" C++.
If what you mean is that you want to have a library that uses this as a logging mechanism without knowing the exact instantiating type, I would advice against it.
The only way of doing it while meeting your other requirements (i.e. no virtual functions) is that all your functions/types in the library that need to log are converted into templates that take the Logger type. The net result is that most of your interface becomes a template (although you can probably move a good amount of the implementation to non-templated code, it will make your life much harder than needed, and it will still generate a much larger binary).
If your concern with virtual functions is performance, then you should reconsider your approach and the problems it brings. In particular, logging is expensive. Most logging libraries tackle it by optimizing the non-logging case (by means of macros that avoid calling the logger if the log level/group/... are not enabled), but still leave dynamic dispatch for the actual writting. The cost of the dynamic dispatch is negligible compared with the cost of writing to the console, or a file, or even with the cost of generating the message that will be logged (I am assuming that you not only log literal strings)
The usual approach is to code against a concept, while providing helpers so that users may easily produce types that satisfy one or more of those concepts. As an example, something like boost::iterator_facade is a CRTP helper that makes it easier for a user to write an iterator. Then, that iterator can be used anywhere an iterator is accepted -- for instance in the range constructor of std::vector. Notice how that particular constructor has no foreknowledge of the user-defined type.
In your case, AbstractLogger would be the CRTP helper. The missing piece would be to define e.g. a logger concept. As a result, notice that everything that needs a logger either needs to be implemented as a template or you need a type-erasing container to hold arbitrary loggers.
Concept checks (like those provided by Boost) are convenient for this kind of programming, since they allow to represent a concept with actual code.
Template classes can't be 'put in a library' since they are instantiated by the compiler as specializations of their template parameters.
You may put parameter independent stuff used in the template implementation into a library though.

How to add a asString() / toString() to std::vector?

My situation is a follows: There is some class MyList that will probably get a specific implemenation later on. For now, behavior like std::vector is fine.
However, I really need an easy way to call some kind of asString() / toString() method on it, because I'll need it in test assertions, debug output and so on. The only options I see are:
Public inheritence. I'll never delete such a list through a base-pointer, since there should never be any base pointers. If I do, there will be no pointer members, anyway. However, rule of thumb still states: Don't inherit from stl containers.
Some kind of "global" (actually in a namespace, of course) method that takes an instance of MyList as argument and does the asString() magic for me. In that case, MyList could be a simple typedef for std::vector.
I like neither of those options too much. Is there something else I failed to think of? Or if not - which way should I prefer?
what is wrong about the second approach? that is by far the easiest and also pretty elegant.-
Imagine the alternative of wrapping the vector. that would cause you alot of extra work and glue code that is error prone! I'd go with the function approach for sure!
edit: btw, i almost exclusively use free functions(sometimes static members) for conversions. Imagine you have a load of types that somehow need to be convertible to string. Having the toString() functions as free functions and not as members does not give you the headache you are heaving right now since you can basically simply overload the function as much as you want and don't have to touch any existing classes (or maybe classes that you don't even have source access to).
Then you can have a function like:
template<class T>
void printDebugInfo(const T & _obj)
{
std::cout<<toString(_obj)<<std::endl;
}
and you wont have the constraints you are experiencing.
Actually, free functions upon class types are a standard technique and are considered as part of the interface of a type. Read this GotW by Herb Sutter, one of people that have a voice in C++ standardization.
In general, prefer free functions over member functions. This increases encapsulation and re-usability and reduces class bloat and coupling. See this article by Scott Meyers for deeper information (highly regarded for his C++ books that you should definitely read if you want to improve your effective and clean use of C++).
Also note that you should never derive from STL containers. They are not designed as base classes and you might easily invoke undefined behaviour. But see Is there any real risk to deriving from the C++ STL containers? .
I think having a free
std::string toString( const MyList &l );
function is perfectly fine. If you are afraid of name clashes, you can consider a namespace as you said. This function is highly decoupled, and won't be able to tinker with private members of MyList objects (as is the case for a member or a friend function).
The only reason which would justify not making it a free function: you notice that you suddenly need to extend the public interface of MyList a lot just to be able to implement toString properly. In that case, I'd make it a friend function.
If you did something like:
template<typename T>
std::ostream& operator<< (std::ostream &strm, const MyList<T> &list)
{
if (list.empty())
return strm;
MyList<T>::const_iterator iter = list.begin(),
end = list.end();
// Write the first value
strm << *iter++;
while (iter != end)
strm << "," << *iter++;
return strm;
}
Then you would essentially have a to string for anything in the list, as long as the elements implement the streaming operator
Have you considered composition, as opposed to inheritance? i.e. Your MyList has a member variable of type std::vector.
You may complain that you will now need to replicate the API of std::vector in MyList. But you say that you might change the implementation later, so you'll need to do that anyway. You may as well do it straight away, to avoid having to change all the client code later on.
Inheritance is completely wrong in this case.
Global function approach is perfectly fine.
One of 'the ways' in C++ is to overload operator << and use stringstream, for example, to output your vector or something else.
I would go with global template function printOnStream. That way you can easily add support for other data types and using stream is more general than creating a string.
I would not use inheritance because there might be some tricky cases. Basic thing is as you mentioned - lack of virtual destructor. But also everything that expects std::vector won't work properly with your data type - for example you can run into slicing problem.
Why don't your debug and assert methods do this for you?

Why bother with virtual functions in c++?

This is not a question about how they work and declared, this I think is pretty much clear to me. The question is about why to implement this?
I suppose the practical reason is to simplify bunch of other code to relate and declare their variables of base type, to handle objects and their specific methods from many other subclasses?
Could this be done by templating and typechecking, like I do it in Objective C? If so, what is more efficient? I find it confusing to declare object as one class and instantiate it as another, even if it is its child.
SOrry for stupid questions, but I havent done any real projects in C++ yet and since I am active Objective C developer (it is much smaller language thus relying heavily on SDK's functionalities, like OSX, iOS) I need to have clear view on any parallel ways of both cousins.
Yes, this can be done with templates, but then the caller must know what the actual type of the object is (the concrete class) and this increases coupling.
With virtual functions the caller doesn't need to know the actual class - it operates through a pointer to a base class, so you can compile the client once and the implementor can change the actual implementation as much as it wants and the client doesn't have to know about that as long as the interface is unchanged.
Virtual functions implement polymorphism. I don't know Obj-C, so I cannot compare both, but the motivating use case is that you can use derived objects in place of base objects and the code will work. If you have a compiled and working function foo that operates on a reference to base you need not modify it to have it work with an instance of derived.
You could do that (assuming that you had runtime type information) by obtaining the real type of the argument and then dispatching directly to the appropriate function with a switch of shorts, but that would require either manually modifying the switch for each new type (high maintenance cost) or having reflection (unavailable in C++) to obtain the method pointer. Even then, after obtaining a method pointer you would have to call it, which is as expensive as the virtual call.
As to the cost associated to a virtual call, basically (in all implementations with a virtual method table) a call to a virtual function foo applied on object o: o.foo() is translated to o.vptr[ 3 ](), where 3 is the position of foo in the virtual table, and that is a compile time constant. This basically is a double indirection:
From the object o obtain the pointer to the vtable, index that table to obtain the pointer to the function and then call. The extra cost compared with a direct non-polymorphic call is just the table lookup. (In fact there can be other hidden costs when using multiple inheritance, as the implicit this pointer might have to be shifted), but the cost of the virtual dispatch is very small.
I don't know the first thing about Objective-C, but here's why you want to "declare an object as one class and instantiate it as another": the Liskov Substitution Principle.
Since a PDF is a document, and an OpenOffice.org document is a document, and a Word Document is a document, it's quite natural to write
Document *d;
if (ends_with(filename, ".pdf"))
d = new PdfDocument(filename);
else if (ends_with(filename, ".doc"))
d = new WordDocument(filename);
else
// you get the point
d->print();
Now, for this to work, print would have to be virtual, or be implemented using virtual functions, or be implemented using a crude hack that reinvents the virtual wheel. The program need to know at runtime which of various print methods to apply.
Templating solves a different problem, where you determine at compile time which of the various containers you're going to use (for example) when you want to store a bunch of elements. If you operate on those containers with template functions, then you don't need to rewrite them when you switch containers, or add another container to your program.
A virtual function is important in inheritance. Think of an example where you have a CMonster class and then a CRaidBoss and CBoss class that inherit from CMonster.
Both need to be drawn. A CMonster has a Draw() function, but the way a CRaidBoss and a CBoss are drawn is different. Thus, the implementation is left to them by utilizing the virtual function Draw.
Well, the idea is simply to allow the compiler to perform checks for you.
It's like a lot of features : ways to hide what you don't want to have to do yourself. That's abstraction.
Inheritance, interfaces, etc. allow you to provide an interface to the compiler for the implementation code to match.
If you didn't have the virtual function mecanism, you would have to write :
class A
{
void do_something();
};
class B : public A
{
void do_something(); // this one "hide" the A::do_something(), it replace it.
};
void DoSomething( A* object )
{
// calling object->do_something will ALWAYS call A::do_something()
// that's not what you want if object is B...
// so we have to check manually:
B* b_object = dynamic_cast<B*>( object );
if( b_object != NULL ) // ok it's a b object, call B::do_something();
{
b_object->do_something()
}
else
{
object->do_something(); // that's a A, call A::do_something();
}
}
Here there are several problems :
you have to write this for each function redefined in a class hierarchy.
you have one additional if for each child class.
you have to touch this function again each time you add a definition to the whole hierarcy.
it's visible code, you can get it wrong easily, each time
So, marking functions virtual does this correctly in an implicit way, rerouting automatically, in a dynamic way, the function call to the correct implementation, depending on the final type of the object.
You dont' have to write any logic so you can't get errors in this code and have an additional thing to worry about.
It's the kind of thing you don't want to bother with as it can be done by the compiler/runtime.
The use of templates is also technically known as polymorphism from theorists. Yep, both are valid approach to the problem. The implementation technics employed will explain better or worse performance for them.
For example, Java implements templates, but through template erasure. This means that it is only apparently using templates, under the surface is plain old polymorphism.
C++ has very powerful templates. The use of templates makes code quicker, though each use of a template instantiates it for the given type. This means that, if you use an std::vector for ints, doubles and strings, you'll have three different vector classes: this means that the size of the executable will suffer.

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?

How to overload operators and not to use both "Curiously Recurring Template Pattern" and "Run Time polymorphism"

I simply want to overload + and = operators in a "Number" class.
I want to have two child class A. Integer B. Fraction, which implements "Number" class. Currently below is how my code looks like. But here I am using both Static and Run time polymorphism paradigm. How to avoid it?
Code Snippet:
Number class:
template<class T>
class Number
{
virtual T& operator= (const T &) = 0;
virtual const T operator+ (const T &) = 0;
virtual void display(std::ostream &) = 0;
};
Integer Class:
// operator "=" overloading
Integer& Integer::operator=(const Integer &secondNumber)
{
intValue = secondNumber.intValue;
return *this;
}
// operator "+" overloading
const Integer Integer::operator+(const Integer &secondNumber)
{
Integer temp;
temp.intValue = this->intValue + secondNumber.intValue;
return temp;
}
Also, if I remove "template" from my "Number" class I cannot overload + operator as it returns class instance, and we cannot have an instance of abstract class which is "Number class"
Also, if I cannot take virtual keyword out, as I want my child to implement the methods present in "Number class".
Kindly guide me a little here on is there any way to not have both type of Paradigm in code i.e, static and dynamic.
You need to decide which method you would prefer, and maybe also why you only want to use the one. However I do not see compile time polymorphism in your code, You are simply creating multiple instantiations of a generic template. The two instantiations have nothing in common, unless they too inherit a common interface.
And with regards to deciding which method to use, rather than looking at what you aim to get out of the code, what I have found is: you need to decide what features you do not need, or might not want included in your design.
Here is a very limited list of points, these may be good or bad depending on your situation:
Compile time polymorphism.
Efficient; no virtual calls required, code can be optimized very well by compiler.
Very strict (no base defined virtual functions): no derived implementation, boom, no compile.
The base object (from a dynamic perspective) is not common, but unique to the template instantiation.
Mixing lots of instantiations can create a large overhead (you could also abstract your design further to mitigate this).
Dynamic polymorphism.
Unique (derived) types contain a common interface.
As soon as you use a base pointer or reference, you can loose some optimizations (compile-time method can inline everything that is well defined and available in the current source, if it wants to).
Unless a virtual function is pure: no implementation, no worries, no error (compile time, you'll have to discover a run-time error).
I can assume by your Number class you do not need an array of mixed types (Number<int> & Number<float>). If this is the case, a compile time solution may be suitable. However if you want to create a function which can operate on any form of Number then you'll have to either remove the template from Number or implement the function as a template also (may end up with code duplication for every T).
Update your question with more specific needs and the correct method, or combination, will be more apparent. I'll update this answer also.
Most of my points come from working with embedded systems. Consideration of the system capabilities is needed to make a well defined decision. Making code very abstract and confusing to the naked eye may not be worth it if you can plunder resources with little effect on the users experience.