I assume that in decltype(expr), expr is not evaluated, but I can't find
wording
to that effect in N2800. Can somebody point me to the guarantee or
disabuse me
of my incorrect assumption?
Thanks,
Scott
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
The difference is that result_of requires a function signature (f and
args are types) and decltype requires a valid expression (f = function/
function pointer/reference/functor, args = objects).
Another question you could ask is: Why do we need result_of where we
have the Callable concept std::Callable<f,args>::result_type. The
answer to that would be: concepts only work in templates (as fas as I
know) and Callable requires you to specify the types 'f' and 'args'
separately whereas result_of only requires one type (function
signature).
> I assume that in decltype(expr), expr is not evaluated, but I can't find
> wording
> to that effect in N2800. Can somebody point me to the guarantee or
> disabuse me
> of my incorrect assumption?
I think it's a safe bet to say decltype doesn't evaluate the
expression (except for the type). It can be used in contexts where
expressions can't be evaluated (outside of a function's body, for
example).
auto foo(int a, int b) -> decltype(a+b)
{ return a+b; }
Cheers!
SG
In C++0x, what is the difference between decltype(f(args)) and
result_of<f(args)>::type? If there is no difference, why do we
need both, e.g.,
why don't we just leave result_of in std::tr1?
decltype applies to expressions, and result_of applies to (abused) types.
struct S
{
int operator()(int);
};
S s;
decltype(s(3)) // int
result_of<S(int)>::type // int
typedef int (*pf)(int);
int f(int);
decltype(f(3) // int
result_of<pf(int)>::type // int
I assume that in decltype(expr), expr is not evaluated, but I
can't find wording
to that effect in N2800. Can somebody point me to the guarantee
or disabuse me
of my incorrect assumption?
It's in an unnumbered paragraph (probably should be numbered)
immediately after [dcl.type.simple]/4:
The operand of the decltype specifier is
an unevaluated operand (Clause 5).
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)
Result_of and decltype are quite different beasts. While decltype
evaluates a given expression, result_of evaluates a *constructed*
expression from the given template argument type. The difference
becomes clearer with an example. Consider
struct A {
double operator()(bool, int);
};
To determine the result type of the operator()
overload you would evaluate
std::result_of<A(bool, int)>::type
but above declaration doesn't allow you directly to
use decltype. You would be required to apply your
own construction by writing something like
decltype(((*((A*)0))(false, 0));
to determine the result of the operator() overload.
In this sense result_of is much nearer to
concept Callable than to decltype, where you
would write
std::Callable<A, bool, int>::result_type
instead.
I can easier think of result_type as some kind of
type trait and it's specification should be moved
to 20.6.2 [meta.type.synop] instead.
> I assume that in decltype(expr), expr is not evaluated, but I can't find
> wording
> to that effect in N2800. Can somebody point me to the guarantee or
> disabuse me
> of my incorrect assumption?
N2857, 7.1.6.2 [dcl.type.simple]/2:
"[..] The operand of the decltype specifier is an unevaluated operand
(Clause 5)."
Greetings from Bremen,
Daniel
On May 7, 2:16 pm, Scott Meyers <use...@aristeia.com> wrote:
> In C++0x, what is the difference between decltype(f(args)) and
> result_of<f(args)>::type? If there is no difference, why do we need
> both, e.g.,
> why don't we just leave result_of in std::tr1?
>
> I assume that in decltype(expr), expr is not evaluated, but I can't find
> wording
> to that effect in N2800. Can somebody point me to the guarantee or
> disabuse me
> of my incorrect assumption?
>
> Thanks,
>
> Scott
>
> --
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@netlab.cs.rpi.edu]
Scott Meyers wrote:
> In C++0x, what is the difference between decltype(f(args)) and
> result_of<f(args)>::type? If there is no difference, why do we need
> both, e.g.,
> why don't we just leave result_of in std::tr1?
>
Whereas result_of takes a type, decltype takes an expression.
> I assume that in decltype(expr), expr is not evaluated, but I can't find
> wording
> to that effect in N2800. Can somebody point me to the guarantee or
> disabuse me
> of my incorrect assumption?
7.1.6.2/4 says:
The operand of the decltype specifier is an unevaluated operand
James
The paragraph describing result_of is hard to understand, but I
believe that result_of<F(Args)>::type == remove_reference<decltype(f
(args))>::type.
Even if this is not so, the obvious advantage of result_of is that you
don't have to obtain instances of F or Args by some dirty trick. In my
equality above, how would I write f and args?
> I assume that in decltype(expr), expr is not evaluated, but I can't find
> wording
> to that effect in N2800. Can somebody point me to the guarantee or
> disabuse me
> of my incorrect assumption?
7.1.6.2/p4 says: "The operand of the decltype specifier is an
*unevaluated* operand." (emphasis mine)
Sebastian
Interesting. I thought it was a "std::function"-like function
signature which in this case -- S(int) -- returned an object of type
S. But after checking N2857 again a conforming definition of result_of
seems to be
template<typename T> class result_of; // undefined
template<typename Fn, typename ... Args>
requires std::Callable<Fn,Args...> // <-- missing in the draft?
class result_of<Fn(Args...)> {
public:
typedef std::Callable<Fn,Args...>::result_type type;
};
Cheers!
SG
--
You are correct in that decltype does not evaluate its argument.
In N2875, this is stated in [dcl.type.simple]/4 as "The operand of the
decltype specifier is an unevaluated operand (Clause 5)."
I'm guessing it was the same location in N2800, but I did not check.
When I read 3.4.3.3 correctly, you can use concepts anywhere.
So
typename result_of<...>::type
would be equivalent to
Callable<...>::result_type
, useable anywhere you can specify a type,
and you don't need the keyword 'typename'.
--
Thomas
Nice. Right. It reminded me that something similar is done in the for-
range loop where
for (... : (range expression)) ...
is translated to
{
auto && __range = (range expression);
for(auto __beg = std::Range<__RangeT>::begin(__range),
__end = std::Range<__RangeT>::end(__range);
...
}
The type __RangeT is probably something like "typename
remove_reference<decltype(__range)>::type".
Cheers!
SG
decltype applies to expressions, and result_of applies to (abused) types.
It took a while for the now-obvious followup question to dawn on me:
why isn't decltype permitted to work with types? sizeof takes both
expressions and types, so why not decltype?
>From what I can tell, C++0x introduces three different ways to figure
out the return type of a function call: decltype, result_of, and
Callable. Callable is a concept, so it serves an independent role
from that of decltype and result_of, but is there a reason why
decltype can't subsume the role of result_of, allowing result_of to be
removed (while still remaining in TR1)?
Scott
--
As I understand it, the publication of C++1x with withdraw TR1 as a
normative standard, meaning all functionality must be in C++1x or not
at all. I could definitely be incorrect on this point, though. Someone
mind confirming/denying?
Sean Hunt
Surely decltype on a type could only be an identity operation. Why
should it give the return type of a function type?
James
I don't know what "C++1x" refers to, but there are no plans to withdraw TR1.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
TR1 is a technical report, not a standard, and even the final version (
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf ) has
"Draft"
in the title. Furthermore, TR1 implementations that currently exist are
not
going to go away, so any code dependent on TR1 functionality that is not in
C++0x will be fine.
If decltype could be extended to apply to types as well as expressions,
it would
eliminate the need for result_of to be in the C++0x standard library
and would
eliminate a seemingly-gratuitous inconsistency between the applicability of
sizeof and decltype. However, I don't know if there are technical
reasons why
decltype needs to be restricted to expressions.
Scott
This is a good point, but I guess I was thinking about an
expression-like form with types. That is, given,
int f(int);
decltype(f(22)) yields int. I agree that
decltype(int(int)); // not legal, but if it were
would return int(int). (Or maybe int (&)(int) -- I don't remember the
exact rules.) But f(int) is neither a type nor an expression, it's a
function call expression with a type supplied instead of an actual
argument. So it's not
unreasonable, I don't think, for
decltype(f(int)); // also not legal
to treat this the same as f(22) above. After all, the only thing that
matters in the expression is the type of the argument, not its value.
Scott
Well, yes, DTR 19768 has "draft" in its title. "DTR" stands for "Draft
Technical Report". TR 19768:2007, published by ISO, does not, since
it's not a draft.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
My understanding is that the DTR is essentially the same as the final
report (which I actually didn't even know existed). Is that correct?
Scott
--
The technical content is the same. ISO may have modified the presentation.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)
[ comp.std.c++ is moderated. To submit articles, try just posting with ]