Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Function returning a reference

46 views
Skip to first unread message

Paul

unread,
Jun 11, 2015, 5:35:54 PM6/11/15
to
The below is quoted from a C++ text. However, I have been unable to implement the idea. Whenever I try, I get the warning for a function returning a reference to a local variable and a runtime error. Does anyone see how to make the idea work?

For example, a typical simple-as-possible findMax implementation would be something like

int findMax(std::vector<int> vec)
{
if(vec.empty())
throw std::runtime_error("Empty vector");

int max = vec[0];
for(int i = 1; i < vec.size(); ++i)
if(vec[i] > max)
max = vec[i];


return max;

}

If we change the signature to return a reference, I understand perfectly that we get an error because we're returning a reference to the local variable max. But if we don't do that, what does the author have in mind?

Many thanks for your help.

BEGIN QUOTE
Suppose we have a function findMax that returns the largest value in a vector or other large collection. Then given a vector arr, if we invoke findMax, we would naturally write
auto x = findMax( arr );
However, notice that if the vector stores large objects, then the result is that x will be a copy of the largest value in arr. If we need a copy for some reason, that is fine; however, in many instances, we only need the value and will not make any changes to x. In such a case, it would be more efficient to declare that x is another name for the largest value in arr, and hence we would declare x to be a reference (auto will deduce constness; if auto is not used, then typically a non-modifiable reference is explicitly stated with const):
auto & x = findMax( arr );
Normally,this means that findMax would also specify a return type that indicates a reference variable.
END QUOTE
Message has been deleted

Paul

unread,
Jun 11, 2015, 6:07:31 PM6/11/15
to
On Thursday, June 11, 2015 at 10:54:39 PM UTC+1, Stefan Ram wrote:
> Paul <peps...@gmail.com> quoted:
> >we would declare x to be a reference
>
> You can return a reference.
>
> The reference does not have to be a reference
> to a local variable.
>
> It also might be a reference to an object that
> has a sufficient lifetime (or a subobject of
> such an object). For example:
>
> #include <iostream>
> #include <ostream>
> #include <array>
>
> int & get2( ::std::array< int, 5 > a )
> { return a[ 2 ]; }
>
> int main()
> { ::std::array< int, 5 >a ={ 4, 12, 22, 17, 41 };
> ::std::cout << get2( a )<< '\n'; }
>
> The object a[ 2 ] has a lifetime that transcends
> the lifetime of get2( a ).

Thanks. Do you know how to implement the idea in the quoted passage?

Paul

Ben Bacarisse

unread,
Jun 11, 2015, 6:51:39 PM6/11/15
to
Paul <peps...@gmail.com> writes:

> The below is quoted from a C++ text. However, I have been unable to
> implement the idea. Whenever I try, I get the warning for a function
> returning a reference to a local variable and a runtime error. Does
> anyone see how to make the idea work?
>
> For example, a typical simple-as-possible findMax implementation would
> be something like
>
> int findMax(std::vector<int> vec)
> {
> if(vec.empty())
> throw std::runtime_error("Empty vector");
>
> int max = vec[0];
> for(int i = 1; i < vec.size(); ++i)
> if(vec[i] > max)
> max = vec[i];
>
>
> return max;
>
> }
>
> If we change the signature to return a reference, I understand
> perfectly that we get an error because we're returning a reference to
> the local variable max. But if we don't do that, what does the author
> have in mind?

I suspect the author is thinking of something like

const int& findMax(const std::vector<int>& vec)
{
if(vec.empty())
throw std::runtime_error("Empty vector");

int maxi = 0;
for(int i = 1; i < vec.size(); ++i)
if(vec[i] > vec[maxi])
maxi = i;
return vec[maxi];
}

<snip>
> However, notice that if the vector stores large objects, then the
> result is that x will be a copy of the largest value in arr. If we
> need a copy for some reason, that is fine; however, in many instances,
> we only need the value and will not make any changes to x. In such a
> case, it would be more efficient to declare that x is another name for
> the largest value in arr, and hence we would declare x to be a
> reference (auto will deduce constness; if auto is not used, then
> typically a non-modifiable reference is explicitly stated with const):
> auto & x = findMax( arr );
> Normally,this means that findMax would also specify a return type that
> indicates a reference variable.

--
Ben.

Kalle Olavi Niemitalo

unread,
Jun 11, 2015, 7:41:08 PM6/11/15
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

> I suspect the author is thinking of something like
>
> const int& findMax(const std::vector<int>& vec)

To the OP: It is important to pass the vec parameter by
reference. If it were passed by value, then its elements would
be deallocated at the end of the function, and the returned
reference to one of the elements would become invalid, even
though the compiler probably would not notice the problem.
The std::array example that was posted earlier in this thread
has that bug.
Message has been deleted

Victor Bazarov

unread,
Jun 11, 2015, 9:05:28 PM6/11/15
to
On 6/11/2015 5:54 PM, Stefan Ram wrote:
> Paul <peps...@gmail.com> quoted:
>> we would declare x to be a reference
>
> You can return a reference.
>
> The reference does not have to be a reference
> to a local variable.
>
> It also might be a reference to an object that
> has a sufficient lifetime (or a subobject of
> such an object). For example:
>
> #include <iostream>
> #include <ostream>
> #include <array>
>
> int & get2( ::std::array< int, 5 > a )
> { return a[ 2 ]; }
>
> int main()
> { ::std::array< int, 5 >a ={ 4, 12, 22, 17, 41 };
> ::std::cout << get2( a )<< '\n'; }
>
> The object a[ 2 ] has a lifetime that transcends
> the lifetime of get2( a ).

Does it? Your 'get2' function takes its argument by what, value,
pointer or reference? Proceed answering my first question after
answering my second, please.

V
--
I do not respond to top-posted replies, please don't ask
Message has been deleted

Rosario19

unread,
Jun 12, 2015, 3:41:14 AM6/12/15
to
On Thu, 11 Jun 2015 14:35:44 -0700 (PDT), Paul wrote:

>The below is quoted from a C++ text. However, I have been unable to implement the idea. Whenever I try, I get the warning for a function returning a reference to a local variable and a runtime error. Does anyone see how to make the idea work?
>
>For example, a typical simple-as-possible findMax implementation would be something like
>
>int findMax(std::vector<int> vec)
>{
> if(vec.empty())
> throw std::runtime_error("Empty vector");
>
> int max = vec[0];
> for(int i = 1; i < vec.size(); ++i)
> if(vec[i] > max)
> max = vec[i];
>
>
> return max;
>
>}
>
>If we change the signature to return a reference, I understand perfectly that we get an error because we're returning a reference to the local variable max. But if we don't do that, what does the author have in mind?

i don't know too much in the few i know
i think something as:

int& findMax(std::vector<int> vec)
{static int max;

if(vec.empty())
throw std::runtime_error("Empty vector");

max = vec[0];
for(int i = 1; i < vec.size(); ++i)
if(vec[i] > max)
max = vec[i];
return max;

}

if it is need one more big obj it is enought one static obj

it is *not ok* when the function is used many thread at once togheter
or in case 1 thread as in (a+b) + (a+c)

[if "+" return a reference to a static object always the same without
use = to somenting other ]

Louis Krupp

unread,
Jun 12, 2015, 4:58:29 AM6/12/15
to
On Fri, 12 Jun 2015 09:41:02 +0200, Rosario19 <R...@invalid.invalid>
wrote:
No. Don't do this. Ever.

Louis

Rosario19

unread,
Jun 12, 2015, 5:53:13 AM6/12/15
to
i'm not agree in your answer...

i agree in the my cousin answer :
"se non sbagli non impari ovvero se non commetti degli errori non puoi
correggerli"

"if you're not wrong you will not learn how you can correct mistakes"

i don't say i'm right...

Öö Tiib

unread,
Jun 12, 2015, 8:10:50 AM6/12/15
to
There is generic standard algorithm for finding max element from range
of elements. It returns iterator (or pointer on case of raw array) to the
element:

int& element = *std::max_element( vec.begin(), vec.end() );

Why to write functions that attempt to do same thing in defective, less
efficient and/or constrained way?
0 new messages