C++ Functors explanation [duplicate] - c++

This question already has answers here:
What are C++ functors and their uses?
(14 answers)
Closed 7 years ago.
Could you please explain following statements with example
Statement1
Ordinary functions have different types only when their signatures differ. However, function objects can have different types
when their signatures are the same. In fact, each functional behavior
defined by a function object has its own type. This is a significant
improvement for generic programming using templates because you can
pass functional behavior as a template parameter

Ordinary functions have different types only when their signatures differ.
Meaning that these functions both have the same type int(int):
int f1(int);
int f2(int);
while this has a different type void(int)
void f3(int);
However, function objects can have different types when their signatures are the same.
Meaning that these two classes are different types (as different classes always are):
class c1 {int operator()(int);};
class c2 {int operator()(int);};
In fact, each functional behavior defined by a function object has its own type.
I don't know exactly what the author means by "functional behaviour", but I think this is just restating that two class types are separate types.
This is a significant improvement for generic programming using templates because you can pass functional behavior as a template parameter
Meaning that you can specify a function class as a template type parameter:
temp<c1> thing_using_c1;
temp<c2> thing_using_c2;
But you can't specify a plain function that way, you'd need to supply the function some other way:
temp<int(int)> thing_using_f1(f1);
temp<int(int)> thing_using_f2(f2);

different classes can have different functions with the same name and its parameters. but in general non class functions thats not possible

Related

Is it possible to define a non-template function that can take a templated object as a parameter

I am using a C++ class which is templated.
I instantiate two different templated version of this class:
ExampleClass<ParamType1> obj1;
ExampleClass<ParamType2> obj2;
So that I have two objects which are the same class, but with different template parameters.
I now want to be able to define a function (extremely simplified example!) that can take either obj1 or obj2 as a parameter:
int func(ExampleClassXXX obj_param)
{
return obj_param.member_operation();
}
So that I can call either func(obj1) or func(obj2.
Is this something that is possible, and if so, what is the syntax needed for the function definition to specify the obj_param parameter is "an instance of ExampleClass created with any template parameters"?
The answer to this question sort of covers the case that is one step more general - having "obj_param" be any type. Most of the details are missing from the text of that answer, it is only when you click on the "live demo" that you see they are instantiating a templated struct to be able to pass in the generic parameter, which is pretty ugly.
It seems like this should be a common thing to want to do, but Googling has failed me so far (searching for "passing templated object as function parameter")
Note that
ExampleClass<ParamType1>
and
ExampleClass<ParamType2>
are basically two different classes for the language.
You have two possibilities, in my opinion, the first being:
template<typename ParamType>
int func(ExampleClass<ParamType> obj_param){}
The second possibility is to give to ExampleClass a non-templated public base class (basically implementing type erasure) like so
template<typename T>
class ExampleClass : public ExampleClassBase{};
and then re-write the function as
int func(ExampleClassBase& obj_param){}
but you will not be able to pass by value in this case because of object slicing issues.
The template function forces you to implement the function in a header file if you want to keep it as general as possible, the non-templated base class forces you to pay for virtual function call.
Edit: as per Alan Birtles comment, if you know already all the types you will instantiate ExampleClass with you can implement each version of the function in a cpp file.
So that I have two objects which are the same class, but with different template parameters.
A contradiction right there. If the arguments are different, this is not the same class. A template is not a class, it's a mold. If you pour two different metals into it, you'd get two very different objects, despite the similar shape. They'd have different mass and density, possibly different electromagnetic properties, and so forth. A bit tangential, but it's important to differentiate the template from the things it produces, those are not the same.
This is why different specializations produced from the same template are considered different classes. They are not related under the type system, and so no function can automatically treat them as the same thing. You could create a function template, and use it to generate functions for each distinct specialization, but those too would be different functions.
If you have a part that's common to all specializations, you could refactor it out into a base class (proper class, not a class template), and have a function that accepts that.

C++ How do compilers handle templates [duplicate]

This question already has answers here:
How does the compilation of templates work?
(7 answers)
Closed last year.
As some of you may know from my recent posts i am studying for a C++ exam which the content for the class was delivered very poorly. I am basically having to self teach everything myself so bear with me here.
This is an exam question:
(i)Explain the concepts of templates as defined in the C++ language.
Be sure to differentiate between what the programmer does and what the
compiler does.
My current rationale:
(i) A template allows a function or class to operate using generics. This allows the programmer to effective program X functionality once, and be able to use this functionality with many different data types without having to rewrite the application or parts of the application multiple times.
My problem is i have no idea how the compiler handles the use of templates.
I am unsure what the compiler does at this stage, if somebody could clear this up it would be helpful.
Templates in C++ are implemented through substitution. It's not like Java generics which just type check the code which involves the generics class and then compiles it using raw references (type erasure).
Basically C++ creates a different class/method for each actual template argument used in your code. If you have your
template<typename T>
void myMethod(T t)
{
//
}
what happens at compile time is that a different method is compiled for each type the template is actually used. If you use it on myMethod(50) and myMethod("foo") then two overloaded version of the method will be available at runtime. Intuitively this means that templates could generate code bloating but in practice the same expressiveness is obtained by a larger codebase without templates with less readability so that's not a real concern.
So there is no black magic behind them (ok there is if you consider meta programming or partial specialization).
let's say you write a function using templates:
template <typename T>
void function(T t){
doSomething();
}
for each data type you call this function, the compiler simply replaces the 'T' with that data type, say 'int' and generates code for that like you've written this function with 'int' instead of 'T' since the beginning.
This is probably the right (but not the complete) answer if others agreed.
For each instance of an object of a different type that you create or in case of functions the different type of arguments that you use, the compiler simply makes an overloaded version at compile time. So if you have a template function like a sort function and use that function for int and double arrays, then the compiler have actually made two functions: one using int and the other using double. This is the simplest explanation I could give. Hope it's useful.

How do to pass variable number of arguments to a function in c++ with no named parameters

I need to write a function which takes a variable number of arguements, its essentially a wrapper around a snprintf like function. I understand how to do this in general as shown in Passing variable number of arguments around.
How ever it appears that, atleast in C, we are required to pass one named parameter to the function before the variable arguments start( Why is void f(...) not allowed in C? ).
However the answers to the same questions say this is easily possible in C++. I was wondering how to achieve this, especially since the method for handling vararg functions seems to be the same as C(va_start, etc). Or are they referring to variadic templates?
So basically is it possible to write a variadic function with no named arguements, as shown below, and if so, how?
void f(...){
...
}
p.s. I would like to do this with c++03 if possible.
While C++ language allows writing functions whose parameter list consist only of ..., the language provides no means for accessing the arguments in functions declared with (...) parameter list.
Basically such functions in C++ exist for their behavior in overload resolution (... parameters match any parameter type). The body of such function will not have access to the arguments. If you see no uses for such functions, just don't use them.
Such functions are often used in non-executed context in some well-known template meta-programming techniques, in which case they don't even have to be defined - a mere declaration is sufficient.

What do the brackets after a declaration of a vector object mean?

I come from a Python background, but I was reading up on the kind of objects and data structures available in the C++ standard library and I see that the declaration for say, a vector of strings:
vector<string> names(10);
Would indicate a vector object initialized to hold 10 objects of type string. My questions are:
Does the <string> part of the declaration have an abstraction to C++ class system, i.e. is it a in built syntax for the vector object or part of some feature of the class system that can be used on user-defined class definitions?
Am I right in assuming that the brackets followed by the name are the arguments passed to the constructor function?
Is string a built-in type like int or an object defined by the standard library. And thus, is there a difference between built-in types and other objects (for instance all "types" are objects in Python)?
There are two sorts of parameters to std::vector objects:
There template arguments which are for std::vector the value type and the allocator types with the latter being defaulted. That is, std::vector<std::string> actually happens to be std::vector<std::string, std::allocator<std::string> >.
There are run-time parameters passed as constructor arguments and std::vector<...> takes quite a few combinations of those. In the above quoted use the 10 is the number of initial elements given to the vector.
So, to answer your concrete questions:
The string happens to be std::string and is nothing special at all. You can use any user-defined type which models certain concepts (e.g. the type needs to be CopyConstructible).
The arguments in the parentheses are the contructor arguments (in the C++ context brackets are normally [ and ] but the term is ambiguous).
string, well, actually std::string is not defined as a built-in type but it is a type from the standard C++ library. How the standard C++ library types are implemented is pretty much up to the C++ implementation, however, i.e., an implementation could choose to make it built-in (as long as it can still be used like a class type).
In C++ there are a few differences between built-in types and class types but with C++ 2011 it is gets pretty close to being able to create class types which behave like built-in types. The primary difference is that it is possible to take the address of certain members of class types while the same "members" are not accessible for built-in types. Another difference is that built-in types don't need to be declared (actually, they cannot be declared) while class types need to be declared and/or defined (depending on how these are used).

compile time polymorphism and runtime polymorphism

I noticed that somewhere polymorphism just refer to virtual function. However, somewhere they include the function overloading and template. Later, I found there are two terms, compile time polymorphism and run-time polymorphism. Is that true?
My question is when we talked about polymorphism generally, what's the widely accepted meaning?
Yes, you're right, in C++ there are two recognized "types" of polymorphism. And they mean pretty much what you think they mean
Dynamic polymorphism
is what C#/Java/OOP people typically refer to simply as "polymorphism". It is essentially subclassing, either deriving from a base class and overriding one or more virtual functions, or implementing an interface. (which in C++ is done by overriding the virtual functions belonging to the abstract base class)
Static polymorphism
takes place at compile-time, and could be considered a variation of ducktyping. The idea here is simply that different types can be used in a function to represent the same concept, despite being completely unrelated. For a very simple example, consider this
template <typename T>
T add(const T& lhs, const T& rhs) { return lhs + rhs; }
If this had been dynamic polymorphism, then we would define the add function to take some kind of "IAddable" object as its arguments. Any object that implement that interface (or derive from that base class) can be used despite their different implementations, which gives us the polymorphic behavior. We don't care which type is passed to us, as long as it implements some kind of "can be added together" interface.
However, the compiler doesn't actually know which type is passed to the function. The exact type is only known at runtime, hence this is dynamic polymorphism.
Here, though, we don't require you to derive from anything, the type T just has to define the + operator. It is then inserted statically. So at compile-time, we can switch between any valid type as long as they behave the same (meaning that they define the members we need)
This is another form of polymorphism. In principle, the effect is the same: The function works with any implementation of the concept we're interested in. We don't care if the object we work on is a string, an int, a float or a complex number, as long as it implements the "can be added together" concept.
Since the type used is known statically (at compile-time), this is known as static polymorphism. And the way static polymorphism is achieved is through templates and function overloading.
However, when a C++ programmer just say polymorphism, they generally refer to dynamic/runtime polymorphism.
(Note that this isn't necessarily true for all languages. A functional programmer will typically mean something like static polymorphism when he uses the term -- the ability to define generic functions using some kind of parametrized types, similar to templates)
"Polymorphism" literally means "many forms". The term is unfortunately a bit overloaded in computer science (excuse the pun).
According to FOLDOC, polymorphism is "a concept first identified by Christopher Strachey (1967) and developed by Hindley and Milner, allowing types such as list of anything."
In general, it's "a programming language feature that allows values of different data types to be handled using a uniform interface", to quote Wikipedia, which goes on to describe two main types of polymorphism:
Parametric polymorphism is when the same code can be applied to multiple data types. Most people in the object-oriented programming community refer to this as "generic programming" rather than polymorphism. Generics (and to some extent templates) fit into this category.
Ad-hoc polymorphism is when different code is used for different data-types. Overloading falls into this category, as does overriding. This is what people in the object-oriented community are generally referring to when they say "polymorphism". (and in fact, many mean overriding, not overloading, when they use the term "polymorphism")
For ad-hoc polymorphism there's also the question of whether the resolution of implementation code happens at run-time (dynamic) or compile-time (static). Method overloading is generally static, and method overriding is dynamic. This is where the terms static/compile-time polymorphism and dynamic/run-time polymorphism come from.
Usually people are referring to run-time polymorpism in my experience ...
When a C++ programmer says "polymorphism" he most likely means subtype polymorphism, which means "late binding" or "dynamic binding" with virtual functions. Function overloading and generic programming are both instances of polymorphism and they do involve static binding at compile time, so they can be referred to collectively as compile-time polymorphism. Subtype polymorphism is almost always referred to as just polymorphism, but the term could also refer to all of the above.
In its most succinct form, polymorphism means the ability of one type to appear as if it is another type.
There are two main types of polymorphism.
Subtype polymorphism: if D derives from B then D is a B.
Interface polymorphism: if C implements an interface I.
The first is what you are thinking of as runtime polymorphism. The second does not really apply to C++ and is a really a concept that applies to Java and C#.
Some people do think of overloading in the special case of operators (+, -, /, *) as a type of polymorphism because it allows you to think of types that have overloaded these operators as replaceable for each other (i.e., + for string and + for int). This concept of polymorphism most often applies to dynamic languages. I consider this an abuse of the terminology.
As for template programming, you will see some use the term "polymorphism" but this is really a very different thing than what we usually mean by polymorphism. A better name for this concept is "generic programming" or "genericity."
Various types of Function overloading (compile time polymorphism ...
9 Jun 2011 ... Polymorphism means same entity behaving differently at different times. Compile time polymorphism is also called as static binding.
http://churmura.com/technology/programming/various-types-of-function-overloading-compile-time-polymorphism-static-binding/39886/
A simple explanation on compile time polymorphism and run time polymorphism from :
questionscompiled.com
Compile time Polymorphism:
C++ support polymorphism. One function multiple purpose, or in short many functions having same name but with different function body.
For every function call compiler binds the call to one function definition at compile time. This decision of binding among several functions is taken by considering formal arguments of the function, their data type and their sequence.
Run time polymorphism:
C++ allows binding to be delayed till run time. When you have a function with same name, equal number of arguments and same data type in same sequence in base class as well derived class and a function call of form: base_class_type_ptr->member_function(args); will always call base class member function. The keyword virtual on a member function in base class indicates to the compiler to delay the binding till run time.
Every class with atleast one virtual function has a vtable that helps in binding at run time. Looking at the content of base class type pointer it will correctly call the member function of one of possible derived / base class member function.
Yes, you are basically right. Compile-time polymorphism is the use of templates (instances of which's types vary, but are fixed at compile time) whereas run-time polymorphism refers to the use of inheritance and virtual functions (instances of which's types vary and are fixed at run time).