[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Passing function objects by reference
From: |
Mats Kindahl |
Subject: |
Re: Passing function objects by reference |
Date: |
10 Oct 2000 19:26:48 +0200 |
Herve Bronnimann <address@hidden> writes:
> Dear all: I have an expensive function object, which holds some internal
> value (a vector, in fact). I don't want to use the copy constructor!
> The problem is that the STL algorithms (in many implementations, and in
> fact this IS required by the standard, for understandable reasons) pass
> this object by value and not by reference.
>
[snip]
> MY QUESTION IS: is this a consequence of the standard, an
> implementation feature proper to g++, and do you believe this should be
> the correct implementation?
AFAIK, it's a consequence of the standard. Sorry, cannot quote the
paragraph right now (just too tired), but it's in 14.8.2.
Template deduction is done without considering the body of the
function and also without considering "enclosing" deductions (this one
has bit me too).
> MY CONCERN IS: why should the presence of internal aux functions change
> the behavior of a function call? And even if that were the normal
> behavior, should we have to know how the library algorithms are
> implemented? I contend that certainly we shouldn't.
I agree with you: a user of a library function/algorithm should not
have to bother about the implementation. In this case, the "fault" is
in the implementor of the "algorithm2" function: he has to explicitly
forward the template argument to the "algorithm" function (see below).
[snip]
> struct binary_pred {
> int i;
> binary_pred() : i(100) {}
> binary_pred( binary_pred const &c) : i(c.i) {
> clog << "copy constructor [with i=" << i++ << "]\n";
> }
> bool operator() (int j, int k) {
> clog << "bool operator() [with i=" << i++ << "]\n";
> return j==k;
> }
> };
>
> template <class Compare>
> void algorithm(Compare comp) { clog << "algorithm\n"; comp(1,2); }
>
> template <class Compare>
> void algorithm2(Compare comp) { clog << "algorithm2\n"; algorithm(comp);
Change this to
template <class Compare>
void algorithm2(Compare comp) {
clog << "algorithm2\n";
algorithm<Compare>(comp);
}
> --------------------------------------------------------------------
>
> This outputs:
>
> Call with algorithm<const binary_pred>
> copy constructor [with i=100]
> algorithm2
> copy constructor [with i=101]
> algorithm
> bool operator() [with i=102]
> Call with algorithm<const binary_pred&>
> algorithm2
> copy constructor [with i=100]
> algorithm
> bool operator() [with i=101]
> Value of comp: 100
Gives me
Call with algorithm<binary_pred>
copy constructor [with i=100]
algorithm2
copy constructor [with i=101]
algorithm
bool operator() [with i=102]
Call with algorithm<binary_pred&>
algorithm2
algorithm
bool operator() [with i=100]
Value of comp: 101
i.e., the copy construction in the second case is not called.
> Replacing algorithm2() calls in main by algorithm() calls outputs:
>
> Call with algorithm<const binary_pred>
> copy constructor [with i=100]
> algorithm
> bool operator() [with i=101]
> Call with algorithm<const binary_pred&>
> algorithm
> bool operator() [with i=100]
> Value of comp: 101
>
> To illustrate that there might be a problem with the compiler, if you
> call algorithm2<const binary_pred &>(comp), it will not generate any
> warnings, even though comp(1,2) is not a const member function. This is
> because instead of algorithm2<const binary_pred &>, it calls
> algorithm2<binary_pred>. You can force the compiler to show it by
> replacing comp(1,2) by comp() and looking at the error message.
Yes, it copies the binary predicate and passes the copy to
"algorithm". Doing the same replacement in the altered code gives me
the following compiler error:
g++ passing.cc -o passing
passing.cc: In function `void algorithm<const binary_pred &>(const
binary_pred &)':
passing.cc:29: instantiated from `algorithm2<const binary_pred &>(const
binary_pred &)'
passing.cc:40: instantiated from here
passing.cc:23: passing `const binary_pred' as `this' argument of `bool
binary_pred::operator ()(int, int)' discards qualifiers
Hope this is of some help,
--
Mats Kindahl, IAR Systems, Sweden
Any opinions expressed are my own, not my company's.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: Passing function objects by reference,
Mats Kindahl <=