Topic: Is std::tr1::function intended to work ONLY with function objects which implement the operator() as const?
Author: Florin Neamtu <neaflo@zappmobile.ro>
Date: Fri, 18 May 2007 11:02:02 CST Raw View
Hi,
I'm using an STL implementation that fails to compile the below code.
So the question is: is the below code standard? Or the behavior is
implementation-specific?
------------------------------------------------------------------------------
#include <functional>
struct functor
{
void operator() (int) { } // not const
};
int main()
{
functor fun;
std::tr1::function<void(int)> f = fun; // Is this standard?
return 0;
}
------------------------------------------------------------------------------
My understanding is that the code is standard compliant. I have looked
into TR1 draft and function::operator() is defined as const - which
leads to the impression that function::operator() must not modify any
internal state of function. Conceptually function::operator() can be
thought as const - forwarding a call to an external entity should not
change the state of [std::tr1::function] instance. So that I find the
const restriction imposed by the standard on function::operator()
reasonable. But I don't find reasonable at all to conclude from this
that when the target callable object is a function object (as in the
above example), the function object must implement operator() as
const! This eliminates the opportunity to use conveniently functors
which modify their state in operator(), which it turn eliminates the
generality of std::tr1::function.
I haven't found yet in the draft any reference regarding the intent to
limit the usage of [std::tr1::function] to calling ONLY function
objects with CONST operator(). I suppose the STL implementation could
use mutable on the internal member(s) maintained by
[std::tr1::function] allowing calls to the non-const operator() of the
target object, while keeping the logical const-ness of
std::tr1::function::operator().
Well, this is my (current) interpretation of TR1 draft regarding
std::tr1::function. At least I didn't find yet a reference in the
standard to contradict it. Please let me know if anyone has more
details of the intent of the standard committee regarding the
behaviour of std::tr1::function in conjunction with function objects.
The above code compiles fine with Boost::Function.
Regards,
Florin Neamtu
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Peter Dimov <pdimov@gmail.com>
Date: Sat, 19 May 2007 22:01:19 CST Raw View
On May 18, 8:02 pm, Florin Neamtu <nea...@zappmobile.ro> wrote:
> Hi,
>
> I'm using an STL implementation that fails to compile the below code.
> So the question is: is the below code standard? Or the behavior is
> implementation-specific?
>
> ------------------------------------------------------------------------------
> #include <functional>
>
> struct functor
> {
> void operator() (int) { } // not const
>
> };
>
> int main()
> {
> functor fun;
> std::tr1::function<void(int)> f = fun; // Is this standard?
> return 0;}
>
> ------------------------------------------------------------------------------
>
> My understanding is that the code is standard compliant.
I believe that you are right and that the code is TR1-compliant. The
requirement of the constructor is that its argument "shall be
callable", and 'fun' fits the definition of Callable. In addition, the
specification of function<>::operator() does not say that the target
is invoked as const, so f(5) should work as well, although this isn't
100% clear from the standard text (even though it's 96% clear in my
opinion).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Florin Neamtu <neaflo@zappmobile.ro>
Date: Mon, 21 May 2007 11:53:18 CST Raw View
On 18 May, 18:41, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> Florin Neamtu ha scritto:
>
> > Hi,
>
> > I'm using an STL implementation that fails to compile the below code.
>
> Could you please post which compiler and the exact error message?
>
> > So the question is: is the below code standard? Or the behavior is
> > implementation-specific?
>
> AFAIK, the code is supposed to be ok. In this case there is no need to
> have an explicit statement allowing such possibility: in absence of an
> explicit statement against it, we can safely assume it's ok.
>
> BTW in the docs of Boost.Function there is an indirect assumption that
> it's possible in section "References to Function Objects" here:http://boost.org/doc/html/function/tutorial.html#id1187118
>
> HTH,
>
> Ganesh
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]
The error is related to the implementation of STL that I currently use
and it doesn't make much sense to this topic. However this is the
header of the error returned by MS Visual C++ 2005 Pro:
error C3848: expression having type 'const functor' would lose some
const-volatile qualifiers in order to call 'void functor::operator ()
(int)'
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Florin Neamtu <neaflo@zappmobile.ro>
Date: Mon, 21 May 2007 12:04:09 CST Raw View
On 20 May, 05:01, Peter Dimov <pdi...@gmail.com> wrote:
> On May 18, 8:02 pm, Florin Neamtu <nea...@zappmobile.ro> wrote:
>
>
>
>
>
> > Hi,
>
> > I'm using an STL implementation that fails to compile the below code.
> > So the question is: is the below code standard? Or the behavior is
> > implementation-specific?
>
> > --------------------------------------------------------------------------- ---
> > #include <functional>
>
> > struct functor
> > {
> > void operator() (int) { } // not const
>
> > };
>
> > int main()
> > {
> > functor fun;
> > std::tr1::function<void(int)> f = fun; // Is this standard?
> > return 0;}
>
> > --------------------------------------------------------------------------- ---
>
> > My understanding is that the code is standard compliant.
>
> I believe that you are right and that the code is TR1-compliant. The
> requirement of the constructor is that its argument "shall be
> callable", and 'fun' fits the definition of Callable. In addition, the
> specification of function<>::operator() does not say that the target
> is invoked as const, so f(5) should work as well, although this isn't
> 100% clear from the standard text (even though it's 96% clear in my
> opinion).
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]- Hide quoted text -
>
> - Show quoted text -
Thanks for the discussion, it seems clear that it's reasonable to have
std::tr1::function instances calling the non-const operator() of the
aggregated functors. Just same as calling non-const member functions.
In fact, the job of std::tr1::function is to forward a call, not at
all to impose restrictions on the target callable object. At least
this was the purpose of such component and it is oulined so in TR1
draft too. I also don't find any technical difficulties or non-
portable issues in implementing it so.
Cheers!
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]