Why can I do this:
stable_sort(it1, it2, binary_function);
but not this:
priority_queue<type, vector<type>, binary_function> pq;
Why can I use a function in the first case, but need an object in the second?
priority_queue is a template and it expects a type as an argument, where is binary_function is a function object.
If you check out the reference on std::stable_sort, you will see that the binary_function you provided, should be a function object as well... There is no difference between the two, except that maybe in the second case there is no proper "cast" or conversion made from a function to a proper function object.
I believe this may be due to the fact that *sort functions use the functor directly, and immediately, thus if the function address is valid when the *sort function is called, it will be valid for the duration of the function call. When creating a container that uses this as a data member (in essence), you can't be sure the function reference will become invalidated during the lifetime of the container object. I know it's a loose handwaving explication, but it's the best I can come up with. Perhaps in C++ the reference to a binary function will be implicitely converted to the construction of a std::function so that the function is "copied" and there is no validity problem.
I hope I haven't lost you now...
Related
i am making some callback system and i wonder if i can reserve function reference to unordered_map so that i can invoke it later.
float func_imp(float x)
{
return x;
}
int main()
{
using Tumap = unordered_map<int, float(&)(float)>;
Tumap umap;
umap.emplace(0, func_imp);
(umap[0])(10.1); //a reference type cannot be value-initialized
using Tvec = vector<float(&)(float)>;
Tvec uvec; // pointer to reference is illegal
//uvec.emplace_back(func_imp);
}
Is it possible to use this type of containers to reserve callback functions? if not, is it the only way to use function pointer?
Regardless of wether this is something you should be doing or not (the comments under your question are covering this already), it's still worth answering your question as is.
The [] operator of map types is a veritable swiss army knife. You can do a lot of things with it.
You can assign a value.
You can lookup the value.
You can lookup a value even if it doesn't exist yet.
Because of this, using that operator imposes some requirements for whatever type is stored in the map. In this specific case, you are running into the requirement that it has to be value-initializable, which references cannot be.
This applies to regular references as well by the way, not just function references.
So the answer is: You can store references in a map as much as you like as long as you don't use any function of the map that requires the reference to do something it's not allowed to.
In this case, you can use umap.at(0)(10.1);. One of the big differences between [] and at() is that if the key is not set yet, at() will throw an exception instead of creating a value-initialized value.
Is it possible to use this type of containers to ...
Regardless of how this sentence continues: No, it is not possible to use this type of containers. Specifically, element type of no standard container can be a reference. Reference types do not satisfy the requirements that containers have for their element type (at least not when using the standard allocator).
if not, is it the only way to use function pointer?
No, function pointer is not the only way, but it is a way that works.
Other alternatives are function objects such as an erasing function wrapper such as std::function, or a reference wrapper such as std::reference_wrapper.
i just thought there is no need to make dereference.
If you mean syntactically, then I have good news that make your concern irrelevant: There is no need to explicitly indirect through a pointer to function. The indirection is implicit just like with function references. Their call syntax is identical Example:
float(&ref)(float) = func_imp;
float(*ptr)(float) = func_imp;
ref(42.);
ptr(42.);
As such, you needen't worry.
If you are talking about having to indirect through the pointer at runtime at the cost of performance, I have bad news that make your concern irrelevant: References are also a form of indirection just as much as pointers are. They are (typically) not an optimisation.
In what circumstances should I prefer pass-by-reference? Pass-by-value?
There are four main cases where you should use pass-by-reference over pass-by-value:
If you are calling a function that needs to modify its arguments, use pass-by-reference or pass-by-pointer. Otherwise, you’ll get a copy of the argument.
If you're calling a function that needs to take a large object as a parameter, pass it by const reference to avoid making an unnecessary copy of that object and taking a large efficiency hit.
If you're writing a copy or move constructor which by definition must take a reference, use pass by reference.
If you're writing a function that wants to operate on a polymorphic class, use pass by reference or pass by pointer to avoid slicing.
There are several considerations, including:
Performance
Passing by value copies the data, so passing large data structures by value can inhibit performance. Passing by reference passes only a reference (basically the address) to the data. For large data structures, this can greatly improve performance. For smaller data structures (like an int), passing by reference can inhibit performance.
Modifications
Passing by value copies the data so if the target code modifies that copy, it will not affect the original. Passing by reference passes only the address of the data, so modifications made against that reference will be "visible" to the calling code.
Yes.
Pass by value for things like native types that are small enough that passing them directly is efficient. Otherwise use pass by (const) reference.
The hard part is writing a template that could apply to either (in which case, you usually want to use pass by reference -- the potential penalty for passing a large object by value is much worse than the potential penalty for passing by reference when passing by value would have been preferred).
Edit: this, of course, is assuming a situation where the required semantics would allow either one -- obviously if you're working with something like polymorphic objects, there's no real "preference" involved, because you must use a pointer or reference to get correct behavior.
As others already have replied to your question sufficiently well, I would like to add an important point:
If the class does not have public copy-constructor, then you don't have choice to pass by value; you have to pass by reference (or you can pass pointer).
The following program would not compile:
class A
{
public:
A(){}
private:
A(const A&) {}
};
//source of error : pass by value
void f(A ) {}
int main() {
A a;
f(a);
return 0;
}
Error:
prog.cpp: In function ‘int main()’:
prog.cpp:10: error: ‘A::A(const A&)’ is private
prog.cpp:18: error: within this context
prog.cpp:18: error: initializing argument 1 of ‘void f(A)’
See yourself at ideone : http://www.ideone.com/b2WLi
But once you make function f pass by reference, then it compiles fine : http://www.ideone.com/i6XXB
here's the simple rule:
pass by reference when the value is large.
the other answers are amazing. Just trying to make this simplest.
You have tagged your question with both C and C++.
Therefore, I suggest that you consider using pass by reference in C++ which supports this feature and that you do not consider using it in C which does not support this feature.
pass by reference can be called only in below conditions:
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function.
Use pass-by-reference if you want to modify the argument value in the calling function. Otherwise, use pass-by-value to pass arguments.
The difference between pass-by-reference and pass-by-pointer is
that pointers can be NULL or reassigned whereas references cannot.
Use pass-by-pointer if NULL is a valid parameter value or if you want to reassign the pointer.
Otherwise, use constant or non-constant references to pass arguments.
While pointers are references, "reference" in c++ usually refers to the practice of tagging a parameter of SomeType&.
Which you should never do. The only place it is appropriate is as a magic syntax required to implement the various pre-defined operators. Otherwise:
You should never pass out parameters by reference - pass by pointer, otherwise you make code reviews all but impossible. Pass by reference makes it impossible to tell by examining a call which parameters can be expected to be changed.
You should never pass in parameter by reference either. Again, this means you are performing a meta optimization. You should always just pass-by-value, otherwise you are guilty of peeking inside an object, examining its implementation and deciding that pass-by-reference is preferred for some reason.
Any c++ class should implement all the copy and assignment constructors and overloads necessary to be passed around by value. Otherwise it has not done its job, of abstracting the programmer from the implementation details of the class.
I am newbie for the concept but as I search the difference and the good of the functors is that they are able to store values inside and initialize these values from the construction but normal functions also work in same fashion except they take the all arguments as whole at the function call. Most probably I am wrong in some way but where is the trick and the benefit of functors in relation to normal functions
The core difference is that a functor defines a type not a function. Even stateless functors (without any attached data) can take advantage of this. For example consider the use of std::less inside a sorting algorithm:
template <typename Iterator, typename Comparator>
sort(Iterator begin, Iterator end, Comparator c) {
...
if (c(*begin,*end)) { ...
...
}
Called as sort(v.begin(), v.end(), std::less<int>());. When the function is called, an instance of std::less<int> is created and passed to the template. Because it is stateless, the cost of passing the function is almost nothing. Inside the function, the call c(a,b) is determined to be a call to c.operator()(a,b), and the compiler knows the type. It can efficiently inline the call (which in this case is simple enough) and substitute it by a single compare instruction.
On the other hand, the equivalent C function qsort takes a function pointer (you cannot pass functions by value). Inside qsort, the compiler does not know what the function called is, and it cannot inline it, so it must perform a function call for each comparison.
Functors serve both to add extra information that can later be used at the place of call (this is impossible with a plain function), and to pass extra information like provide information like what needs to be called (the same behavior can be obtained, but with a hit on performance) or other attached information (the type can have nested types/typedefs, information for traits inspection...)
Normal functions, free-standing or member, only have their arguments which will be passed when the function is called. So there is no way to pass extra data to the function.
This is different with a functor. A functor is an instance of an object, and as such can indeed store data passed to its constructor (which you use when passing the functor).
With C++11 things are muddled up a bit, as lambdas can also "store" (not technically correct word) values by using captures. Or by using std::bind which allows you to bind values as arguments when the callable object is actually called.
In what circumstances should I prefer pass-by-reference? Pass-by-value?
There are four main cases where you should use pass-by-reference over pass-by-value:
If you are calling a function that needs to modify its arguments, use pass-by-reference or pass-by-pointer. Otherwise, you’ll get a copy of the argument.
If you're calling a function that needs to take a large object as a parameter, pass it by const reference to avoid making an unnecessary copy of that object and taking a large efficiency hit.
If you're writing a copy or move constructor which by definition must take a reference, use pass by reference.
If you're writing a function that wants to operate on a polymorphic class, use pass by reference or pass by pointer to avoid slicing.
There are several considerations, including:
Performance
Passing by value copies the data, so passing large data structures by value can inhibit performance. Passing by reference passes only a reference (basically the address) to the data. For large data structures, this can greatly improve performance. For smaller data structures (like an int), passing by reference can inhibit performance.
Modifications
Passing by value copies the data so if the target code modifies that copy, it will not affect the original. Passing by reference passes only the address of the data, so modifications made against that reference will be "visible" to the calling code.
Yes.
Pass by value for things like native types that are small enough that passing them directly is efficient. Otherwise use pass by (const) reference.
The hard part is writing a template that could apply to either (in which case, you usually want to use pass by reference -- the potential penalty for passing a large object by value is much worse than the potential penalty for passing by reference when passing by value would have been preferred).
Edit: this, of course, is assuming a situation where the required semantics would allow either one -- obviously if you're working with something like polymorphic objects, there's no real "preference" involved, because you must use a pointer or reference to get correct behavior.
As others already have replied to your question sufficiently well, I would like to add an important point:
If the class does not have public copy-constructor, then you don't have choice to pass by value; you have to pass by reference (or you can pass pointer).
The following program would not compile:
class A
{
public:
A(){}
private:
A(const A&) {}
};
//source of error : pass by value
void f(A ) {}
int main() {
A a;
f(a);
return 0;
}
Error:
prog.cpp: In function ‘int main()’:
prog.cpp:10: error: ‘A::A(const A&)’ is private
prog.cpp:18: error: within this context
prog.cpp:18: error: initializing argument 1 of ‘void f(A)’
See yourself at ideone : http://www.ideone.com/b2WLi
But once you make function f pass by reference, then it compiles fine : http://www.ideone.com/i6XXB
here's the simple rule:
pass by reference when the value is large.
the other answers are amazing. Just trying to make this simplest.
You have tagged your question with both C and C++.
Therefore, I suggest that you consider using pass by reference in C++ which supports this feature and that you do not consider using it in C which does not support this feature.
pass by reference can be called only in below conditions:
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function.
Use pass-by-reference if you want to modify the argument value in the calling function. Otherwise, use pass-by-value to pass arguments.
The difference between pass-by-reference and pass-by-pointer is
that pointers can be NULL or reassigned whereas references cannot.
Use pass-by-pointer if NULL is a valid parameter value or if you want to reassign the pointer.
Otherwise, use constant or non-constant references to pass arguments.
While pointers are references, "reference" in c++ usually refers to the practice of tagging a parameter of SomeType&.
Which you should never do. The only place it is appropriate is as a magic syntax required to implement the various pre-defined operators. Otherwise:
You should never pass out parameters by reference - pass by pointer, otherwise you make code reviews all but impossible. Pass by reference makes it impossible to tell by examining a call which parameters can be expected to be changed.
You should never pass in parameter by reference either. Again, this means you are performing a meta optimization. You should always just pass-by-value, otherwise you are guilty of peeking inside an object, examining its implementation and deciding that pass-by-reference is preferred for some reason.
Any c++ class should implement all the copy and assignment constructors and overloads necessary to be passed around by value. Otherwise it has not done its job, of abstracting the programmer from the implementation details of the class.
In C++, if an object of a class is passed as a parameter into a function, the copy constructor of the class will be called.
I was wondering if the object is of nonclass type, what function will be called?
Similarly in C, what function is called when passing values or address of variables into a function?
Thanks and regards!
No function will be called; the bytes composing the object will simply be copied to the correct place for the callee (be that a location in memory or a register).
The copy constructor is only called if the object is being passed by value (and is a non-POD type). This is one of the reasons that it is common practice to pass objects by reference and const reference should you not wish the object to be changed by the function.
No function is called.
Since non-object types don't have methods, they are simply copied onto the stack to be used as-is by your function.
It depends on the implementation, but in some cases you may incur a function call if you are passing a floating-point value into a function expecting a value of integral type. (This is an implementation detail rather than part of the language, it's true, but it's no less worth taking account of because of that. And such conversions are often slow in any event, function call required or not.)