C++0x auto and decltype

  • Thread starter Marcin Kaliciñski
  • Start date
R

Rob Williscroft

Marcin Kaliciñski wrote in
in comp.lang.c++:
std::vector<int> v;
auto iter = v.begin();

Will this deduce iter to be std::vector<int>::iterator or
const_iterator? I have been searching for the answer in
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1705.pdf but
couldn't find it. Does anybody know?

The expression v.begin() above returns iterator, because v isn't
const, so the only type 'iter' can be is std::vector<int>::iterator.

The place to find the rules is in the current standard, as the auto
proposal builds on its template paramiter type deduction rules. So
you question boils down to:

template < typename T > void f( T ) {}
int main()
{
f( v.begin() );
}

I.e. What is the type of T above ?

Rob.
 
K

kalita

Marcin Kaliciñski wrote in
in comp.lang.c++:


The expression v.begin() above returns iterator, because v isn't
const, so the only type 'iter' can be is std::vector<int>::iterator.

The place to find the rules is in the current standard, as the auto
proposal builds on its template paramiter type deduction rules. So
you question boils down to:

template < typename T > void f( T ) {}
int main()
{
f( v.begin() );
}

I.e. What is the type of T above ?

That means that auto is useless in shortening code like that:

for (std::vector<int>::const_iterator it = v.begin(); it != v.end();
++it)

because you cannot make it deduce const_iterator. Or am I missing
something?

If auto is so limited, maybe it was good if old proposition of operator
:: being applicable to variables was revived for C++0x standard? I
thought it was abandonned because auto provides better, bigger and
more. But now I am no longer so sure about it. We could then write:

for (v::const_iterator it = v.begin(); it != v.end(); ++it)

I have seen many novices trying to compile that sort of code and
wondering why it is wrong. I think allowing it should not be viewed as
an extension, but more like patching an obvious hole.

cheers,
M.
 
R

Rob Williscroft

wrote in in
comp.lang.c++:
That means that auto is useless in shortening code like that:

for (std::vector<int>::const_iterator it = v.begin(); it != v.end();
++it)

No, if v is a const (or more likely a const &) then auto will work
fine, if v is non-const then very little is gained by making 'it'
a const_iterator, since using an iterator where a const_iterator
should work, *shouldn't* change the programes behaviour.
because you cannot make it deduce const_iterator. Or am I missing
something?

No, but a library solution can fill the gap:

template < typename T >
inline T const & const_ref( T &a )
{
return a;
}

template < typename T >
inline T const & const_ref( T const &a )
{
return a;
}

for (
auto it = const_ref( v ).begin(), lim = const_ref( v ).end();
it != lim;
++it
)
If auto is so limited maybe it was good if old proposition of operator
:: being applicable to variables was revived for C++0x standard? I
thought it was abandonned because auto provides better, bigger and
more. But now I am no longer so sure about it. We could then write:

for (v::const_iterator it = v.begin(); it != v.end(); ++it)

That will be:

for (decltype( v )::const_iterator it = ...

Rob.
 
J

Jakob Bieling

Excuse the question .. but what exactly do I gain by using these
keywords? Apart from the fact that possibly I have to type less. Is
there anything I can do with these keywords, that I could not do without
them, or is this pure syntactic sugar like -> is?

thanks
 
R

Rob Williscroft

Jakob Bieling wrote in in
comp.lang.c++:
Excuse the question .. but what exactly do I gain by using these
keywords? Apart from the fact that possibly I have to type less. Is
there anything I can do with these keywords, that I could not do
without them, or is this pure syntactic sugar like -> is?

thanks

Assume a set of overloaded functions:

some_type f( arg1_type a, arg2_type b );

Then:

template < typename A, typename B >
void contrived( A a, B b )
{
auto r = f( a, b );
std::cout << r << r;
}


Curently the /simple/ way to write the above means calling f(a, b)
twice, with possible side effects and expensive computations
accuring twice.

template < typename A, typename B >
void contrived( A a, B b )
{
std::cout << f( a, b ) << f( a, b );
}

Off the top of my head I've come up with two workaraounds:


1) Use indirection, i.e. put the body of contived in a
helper function, but that could be difficult with a less
simplistic example, or

2) Capture the return of f(a, b) in some kind of holder
object, but that would require an allocation and 2 virtual calls
(one for operator << and one for the destructor).

I'm sure there are others.

The basics of the proposal mean it will be simpler to write clear
and efficient code.

There is however a lot more to the auto/decltype proposal, but
it isn't that long so I suggest you give it a read.

Rob.
 
Y

Yuriy Solodkyy

When you want to write a function that adds say matrix<T> and matrix<U>,
how would you define the type of result of your function? Naturally
you'll want it to be of type matrix<type_of_result_of_operation T+U>.
That's what auto and decltype are targeting.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top