C++ Valarray program compiler error using g++

The below program builds/runs OK in VS 2010 Express, but since we run on Linux, I moved it over. I get a compiler error using g++ version 4.8.2. Not sure what I have to do to get the program to run on Linux. (BTW, my project does not use C++11.)
#include <valarray>
using namespace std;

void foo(valarray<int>& va)
{
   slice_array<int>& sa = va[slice(0,3,2)];
   sa = 98;
}

int main()
{
   valarray<int> valary(21);
   for(size_t i=0; i<valary.size(); ++i)
   {
      valary[i] = i;
   }
   foo(valary);
}

Open in new window

$ g++ slice_array.cpp
slice_array.cpp: In function ‘void foo(std::valarray<int>&)’:
slice_array.cpp:6:42: error: invalid initialization of non-const reference of type ‘std::slice_array<int>&’ from an rvalue of type ‘std::slice_array<int>’
    slice_array<int>& sa = va[slice(0,3,2)];
                                          ^

Open in new window

LVL 33
phoffricAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sarabandeCommented:
invalid initialization of non-const reference of type ‘std::slice_array<int>&’ from an rvalue of type ‘std::slice_array<int>’
the g++ returns an rvalue when you call valarray operator[]. because of that you may not use a non-const reference variable. actually operator[] should have two prototypes, one returning a const reference to the "element" and one a writeable reference. the problem here is that operator[] returns by value and not by reference. the slice object returned therefore is a temporary which the g++ provides as rvalue. i don't know whether one could call it a bug, but probably it shouldn't actually make a difference when using it.

Not sure what I have to do to get the program to run on Linux.
did you try to use a const reference variable. a slice neither can be constructed nor be copied. because of that all public member functions actually should be const anyway.

Sara
0
phoffricAuthor Commented:
As noted in the OP, VS 2010 Express built the above program and it ran as expected. Not sure why that is. Could it be running C++11 instead of C++03? Can I force it to run C++03 as that is what my project uses?

My book says:
slice_array<T> operator[](slice); // references to elements
A slice_array can be copied.
A book from 1997 does say that that slice_arrays cannot be copied, but it does have code similar to the OP code (without a need for adding a const).

I would like VS 2010 Express to behave the same way as g++.
(Be back in 12 hrs.)
0
jkrCommented:
Well, first of all: VC++ 2013 compiles that fine as whell, while my g++ complains about the same - you could solve that by

either

#include <valarray>
using namespace std;

void foo(valarray<int>& va)
{
   slice_array<int> tmp = va[slice(0,3,2)];
   slice_array<int>& sa = tmp;
   sa = 98;
}

int main()
{
   valarray<int> valary(21);
   for(size_t i=0; i<valary.size(); ++i)
   {
      valary[i] = i;
   }
   foo(valary);
}

Open in new window


or

#include <valarray>
using namespace std;

void foo(valarray<int>& va)
{
   slice_array<int> sa = va[slice(0,3,2)]; // <-- no reference works as well,
   sa = 98;
}

int main()
{
   valarray<int> valary(21);
   for(size_t i=0; i<valary.size(); ++i)
   {
      valary[i] = i;
   }
   foo(valary);
} 

Open in new window

0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

sarabandeCommented:
My book says:
slice_array<T> operator[](slice); // references to elements

from syntax slice_array<T> is an object and not a reference. internally it could be a reference (pointer) nevertheless.
the msdn reference says:

The class describes an object that stores a reference to an object of class valarray<Type>, along with an object of class slice, which describes the sequence of elements to select from the valarray<Type> object.

The template class is created indirectly by certain valarray operations and cannot be used directly in the program. An internal, auxiliary template class that is used by the slice subscript operator:

slice_array<Type> valarray<Type::operator[] (slice).

You construct a slice_array<Type> object only by writing an expression of the form va[sl], for a slice sl of valarray va. The member functions of class slice_array then behave like the corresponding function signatures defined for valarray<Type>, except that only the sequence of selected elements is affected.


the visual c++ creates a new temporary object slice_array which therefore can be referenced as lvalue.

the standard reference (http://www.cplusplus.com/reference/valarray/valarray/operator%5B%5D/) says (regarding valarray operator[])

valarray<T> operator[] (slice slc) const;
slice_array<T> operator[] (slice slc);
...
The subscript access versions (2) return a sub-array object that selects the elements specified by its argument:
- If the valarray is const-qualified, the function returns a new valarray object with a copy of this selection.
- Otherwise, the function returns a sub-array object, which has reference semantics to the original array, ready to be used as an l-value.

you see the visual c++ implementation is more compliant to the (both C98 and C++11) standard as it is with g++.

'A slice_array can be copied' versus slice_arrays cannot be copied
in the msdn i read somewhere the statement that slice_array objects cannot be copied.  since you can prevent from copying by defining a private copy constructor and a private operator= it is rather simple. but actually i didn't see a reson why copies should be forbidden. obviously you could create copies anyhow by using the expression va[sl] twice.

the following code compiles (visual studio 2010):

    std::valarray<int> va(3);
    std::slice sl(0,2, 2);
    std::slice_array<int> sa1 = va[sl];
    std::slice_array<int> sa2 = sa1;

Open in new window

what proves that the copy constructor of slice_array was working.

I would like VS 2010 Express to behave the same way as g++.
as told the behavior of vc compiler is compliant to the standard while g++ seems to support valarray operator[] const only and returns an rvalue. i wonder whether g++ allows to create copies of slice_array. if so, you probably should go this way for both platforms rather than to use local references to va[sl]. where the behavior is different.

Sara
0
evilrixSenior Software Engineer (Avast)Commented:
The problem that operator [] returns an r-value (a temporary object in this case).

std::slice_array<T> std::valarray::operator[] (slice slc);

Open in new window


You can't bind an r-value to a non-const l-value reference. You have two choices, either make it a const reference or (if you are using C++11) change it to an r-value reference:

slice_array<int> const & sa = va[slice(0,3,2)]; // bind to const ref

Open in new window


or

slice_array<int>&& sa = va[slice(0,3,2)]; //; bind to r-value ref

Open in new window


A third option is just to return it as a copy of the original temporary.

slice_array<int> sa = va[slice(0,3,2)]; //; take a copy of the returned value

Open in new window

https://www.artima.com/cppsource/rvalue.html

In this case, gcc is correct and Visual Studio is (as usual) wrong!
0
evilrixSenior Software Engineer (Avast)Commented:
Also note that if you are using C++ 11 you can simplify your code to just the following:

auto const & sa = va[slice(0,3,2)]; // bind to const ref

Open in new window


or

auto && sa = va[slice(0,3,2)]; //; bind to r-value ref

Open in new window


or

auto sa = va[slice(0,3,2)]; //; take a copy of the returned value

Open in new window


http://en.cppreference.com/w/cpp/language/auto
0
evilrixSenior Software Engineer (Avast)Commented:
>> as told the behavior of vc compiler is compliant to the standard
Oh, if only it was :(
0
sarabandeCommented:
returns an r-value (a temporary object in this case).

actually the standard doesn't support this assertment. a temporary object and a rvalue are two different things. an rvalue only could be used for the right side of an assignment. a temporary object is an lvalue within the current scope.

the docs for slice_array didn't change from C++98 to C++11. and you can find the following at http://www.cplusplus.com/reference/valarray/valarray/operator%5B%5D/ 

Otherwise, the function returns a sub-array object, which has reference semantics to the original array, ready to be used as an l-value.
what obviously is in contradiction to the visual c++ compiler verdict evilrix has posted.

note, the main purpose of a slice_array object is to provide a comfortable filter to a valarray. the only way to get a slice_array is via valarray operator[slice]. we can recognize a lot of bewilderment - unfortunately also here in this thread - regarding the nature of an object returned by value. but there is no doubts even if it is a temporary, an object returned by value is not an rvalue. if we accept this, g++ obviously doesn't return a temporary helper object but a const reference to either slice_array or valarray what is as far as i can see a contradiction to that what the standard says.

Sara
0
evilrixSenior Software Engineer (Avast)Commented:
>> a temporary object and a rvalue are two different things
A temporary is an r-value, because you are NOT allowed to modify a temporary - hence, it cannot be an l-value and so, by definition, MUST be an r-value. Put another way, a temporary is an r-value but an r-value is not a temporary!

Note, I never said they were the same thing and trust me that you do not need to explain to me what r-value means.

As defined by Herb Sutter (currently the head of the Standards board for the C++14 working group: "We usually call a temporary object an “rvalue,” so named because it can appear on the “r”ight hand side of an assignment".

http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/

>> what obviously is in contradiction to the visual c++ compiler verdict evilrix has posted.
When an object is return by value it is created on the functions stack frame and is, be very definition, temporary. The object is destroyed when the function's stack frame is expunged. The only way to preserve it is to bind it to a const l-value reference, an r-value reference or take a copy.
0
evilrixSenior Software Engineer (Avast)Commented:
>> actually the standard doesn't support this assertment

You mean, like this?

ISO/IEC 14882:2011(E) 78
3.10 Lvalues and rvalues [basic.lval]

An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object."

Or this?

A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [Example: The result of calling a function whose return type is not a reference is a prvalue. The value of a literal such as 12, 7.3e5, or true is also a prvalue. — end example ]
0
evilrixSenior Software Engineer (Avast)Commented:
Working example, compiled on ideone (using gcc that is C++11 compatible).

https://ideone.com/YE8aHc

#include <valarray>
using namespace std;

void foo(valarray<int>& va)
{
   // You can't return by value to a non-const lvalue reference, it either
   // has to be a const lvalue reference or a (C++11) rvalue reference.
   //slice_array<int>& sa = va[slice(0,3,2)];
   slice_array<int>&& sa = va[slice(0,3,2)];
   sa = 98;
}

int main()
{
   valarray<int> valary(21);
   for(size_t i=0; i<valary.size(); ++i)
   {
      valary[i] = i;
   }
   foo(valary);
}

Open in new window


Note that what is returned by the operator [] is an object that has reference semantics, not a reference.

SO/IEC 14882:2011(E) 78
26.6.2.5 valarray subset operations
The non-const versions return a class template object which has reference semantics to the original array
0
sarabandeCommented:
The only way to preserve it is to bind it to a const l-value reference, an r-value reference or take a copy.

again, it is a different thing that a temporary would not "preserve" if you don't bind it to a const reference or take a copy to the fact that it could be used as a lvalue. so the slice_array object returned by va[sl] is a temporary but also can be used as lvalue, what means that you could apply any non-const member function or non-const operator directly by statements like va[sl] *= 10; what apparently could not work if va[sl] was an rvalue.

or:

class X
{
   int m;
 public:
   X(int i) : m(i) {}
   static X GetX(int k) { return X(k); }
   X& operator=(int n) { m = n; return *this; }
   friend std::ostream & operator<<(std::ostream & os, const X & x) { os << x.m; return os; }
};

void f()
{
      std::cout << (X::GetX(999) = 5) << std::endl;
}

Open in new window


rvalue or lvalue?

Sara
0
evilrixSenior Software Engineer (Avast)Commented:
Sara, you are confusing two different things. A values [r/l]value status has nothing to do with its cv qualification. In other words a const is an r-value but an r-value is not necessarily a const. Further, just because you can modify a temporary doesn't make it an l-value.

All "rvalue" means is that it cannot appear on the left hand side of an assignment. The compiler doesn't necessarily have to generate an error if it does but the result is undefined.

Did you read the relevant sections I quoted for you out of the Standards document?

"A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [Example: The result of calling a function whose return type is not a reference is a prvalue. "

Also note what the standard states:

Class prvalues can have cv-qualified types

In other words they can but do NOT have to be cv-qualified (cv = const/volatile)

Regarding your example, note that section 5.2.1.10 states:

A function call is an lvalue if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise.

- clearly it's not returning an lvalue reference
- clearly it's not returning an rvalue reference to a function type,
- clearly it's not returning  an rvalue reference to an object type
- therefore it must be a prvalue

A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [ Example: The result of calling a function
whose return type is not a reference is a prvalue
.

In case you are wondering why a temporary isn't const consider the following code...

https://ideone.com/afbMSJ

#include <iostream>

struct foo
{
	void bar() { std::cout << "Hello, world!" << std::endl; }
};

foo create_foo()
{
	return foo();
}

int main()
{
	// This is perfectly legit even though returned object is an rvalue
	create_foo().bar(); // if temporary was const I could not call bar()
	
	// This is not possible: r-value cannot be bound to a l-value reference
	auto & f = create_foo();
}

Open in new window


Note that if the r-value was const the bar() function could not be called.

Remembering that operators are also just functions, this special case exists (amongst other reasons) to ensure that member operators work correctly, even if the type is an rvalue.

Also, note the error generated when we try to assign to the l-value reference:

prog.cpp: In function 'int main()':
prog.cpp:19:24: error: invalid initialization of non-const reference of type 'foo&' [b]from an rvalue[/b] of type 'foo'
  auto & f = create_foo();

Open in new window


So, put in simple terms: an rvalue is a type that may not be on the left of an assignment; however, that is NOT the same as it being const. The compiler won't stop you making the assignment but the result of modifying an rvalue is undefined. An rvalue type cannot be const otherwise you'd be prevented from calling non-const functions, which is a special case that the standard allows. Also, if it were const explain r-value references, which are most certainly not const (unless explicitly declared so).

More info: http://cpptruths.blogspot.co.uk/2009/08/modifying-temporaries.html

I'm really not sure how much clearer I can make this: Sara, with the deepest respect, you are wrong!
0
phoffricAuthor Commented:
Thanks for this discussion. I appreciate that. I got home much later than expected and now it is past midnight. I will spend more time on this (and I do have Friday off - maybe even Thursday if I get more time in tomorrow along with some success!).

Sorry to be so brief in what should be a more detailed engagement. :(
@jkr - I ran your 2nd program on both VS 2010 Express and g++ to confirm the results. Thanks. It worked without needing const and even without an extra temp. At work I will eventually be doing timing tests. I don't think using a slice_array object will cause much of an issue as long as the reference semantics hold when referring to the valarray object. I use VS 2010 instead of 2013 because I was concerned that C++11 goodies might creep in, and my project is not C++11. (Neither is it pure C++11, because I accidentally found that I could define on the stack an array (even 2d) whose dimension lengths are passed in as function arguments - worked with g++ as well as Intel compilers.)

@sara - your suggested program does work, but I was trying to get my book's style working, and it looks like jkr cracked the l-value, r-value issue (at least as a work-around without introducing const). I believe that "sa" in the OP code is a reference to a slice_array object and that its usage provides reference semantics to the underlying valarray. That was my hope. The intention was to be able to refer to the original valarray object elements in the slice without having to actually copy the slice over to another valarray object. (This exercise is a prelude to using gslice_array on valarrays that are very large, and I would like to try to avoid copying sub-matrix.)

I believe the answer to your question as to why certain operations are prohibited has to do with compiler optimizations that can be performed if the compiler knows that no aliasing will occur. When you seemed to imply that my book was wrong with regards to reference semantics, I started to look at the C++03 standard (and that's why I use the book to avoid that). But that leads to ...

@rx - Glad you joined in because I am hoping to understand what the standard really is saying now that I started looking at it. My post is a simplified version of the book's code (which is already pretty simple), so I wasn't surprised when VS 2010 Express worked. Book is BS's 4th edition, but 3rd special edition has same sample code. Still trying to figure out whether one compiler has a bug, or whether there needs to be flags set to make them strictly conforming to C++03. My boss (and I) should know whether I am producing pure conforming code.

BTW - in the OP I noted that C++11 is not available on my project, so I hope to continue this discussion in a C++03 vein. At work today, I tried using our actual Intel compiler and got the same rvalue error. So, I am still confused as to which compilers are conforming. (I used to think I understood rvalue/lvalue in my C days a long time ago.)

@all:
fyi - The lead asked me to try to come up with a high performance method of using valarray because Intel compiler has flags to enable SIMD when using it. He apparently wasn't happy with previous attempts to make use of it. (And I didn't see any slice_array or gslice_array in their classes, so I am guessing that may be a source of the performance hit due to copying and temporaries being created - just a WAG at this point.) From my other valarray question, you can see that I learned how to create a sub-matrix using gslice_array. But I think there may be copy operations going on that I hope to avoid.

I find it odd that various online resources seem to say opposite things about slice_array w.r.t. the ability to use it explicitly in a program. Yet, jkr's solution shows working programs that explicitly mention slice_arrays and they work on at least two compilers.

Thanks all. Will read all of this in more detail in a few days (or a little at a time).
0
sarabandeCommented:
evilrix, i hope you pardon me if i don't want to dive into the swamp of rvalue, lvalue, prvalue, xvalue, since i am not a compiler expert and much less experienced in studying the secrets of describing a standard than you. i reread all the comments and quotes you made and think i have found a sufficient explanation (sufficient for me) of the difference between the two compilers regarding the temporary slice_array: the difference is the lifetime of the temporary where the standard only guarantees that it is preserved until end-of-scope if it either was copied or bound to a const reference while visual c++ compiler also holds the temporary alive if you bind it to a non-const reference.

it looks like jkr cracked the l-value, r-value issue (at least as a work-around without introducing const).

phoffric, jkr's code made a copy of the temporary slice_array and then an alias to that local copy. since we already knew that copying of slice_array objects was allowed and because taking a copy of a temporary is a valid means to extend the lifetime of the temporary until end-of-scope, the workaround is safe.  

I believe that "sa" in the OP code is a reference to a slice_array object and that its usage provides reference semantics to the underlying valarray. That was my hope.
a slice_array doesn't store own values but has references to valarray elements. in any case the slice_array allows manipulation of the original values within its lifetime. because of that the following code also should work (for both compilers):

void foo(valarray<int>& va)
{
   va[slice(0,3,2)] = 98;
}

Open in new window


but also may confuse again if we think about the following assertments made:

All "rvalue" means is that it cannot appear on the left hand side of an assignment.
with the deepest respect, you are wrong!
(I used to think I understood rvalue/lvalue in my C days a long time ago.)
perhaps we come to the conclusion that all these statements stretch the truth :-)

Sara
0
phoffricAuthor Commented:
Here is the code from The C++ Programming Language, 4th Edition by Bjarne Stroustrup (and I think the function is the same as in the 3rd Special Edition).
A user cannot directly create a slice_array. Instead, the user subscripts a valarray to create a slice_array for a given slice. Once the slice_array is initialized, all references to it indirectly go to the valarray for which it is created. For example, we can create something that represents every second element of an array like this:
void f(valarray<double>& d)
{
  slice_array<double>& v_even = d[slice(0,d.size()/2+d.size()%2,2)];
  slice_array<double>& v_odd = d[slice(1,d.size()/2,2)];
  v_even *= v_odd; // multiply element pairs and store results in even elements
  v_odd = 0; // assign 0 to every odd element of d
}

Open in new window

This code builds/runs well on VS 2010 Express. So, I naively thought that VS was correct and that something was wrong with g++, and was hoping that maybe a g++ flag would set things straight so that I can write one piece of code that works the same on both platforms.
0
sarabandeCommented:
was hoping that maybe a g++ flag would set things straight so that I can write one piece of code that works the same on both platforms.

you may try

d[slice(0,d.size()/2+d.size()%2,2)] *= d[slice(1,d.size()/2,2)];
d[slice(1,d.size()/2,2)] = 0;

Open in new window


or use copies instead of references

 
slice_array<double> v_even = d[slice(0,d.size()/2+d.size()%2,2)];
  slice_array<double> v_odd = d[slice(1,d.size()/2,2)];
  v_even *= v_odd; // multiply element pairs and store results in even elements
  v_odd = 0; // assign 0 to every odd element of d

Open in new window


since the copies reference to the original values in the valarray, the result is the same.

note, the sample shows that Stroustrup would favor the visual c++ way of handling the lifetime of temporaries rather than the g++ way (which claims to be more compliant to the standard as evilrix has elaborated).

Sara
0
phoffricAuthor Commented:
I see that there were some errata to The Programming Language on the BS code; yet attempts to get them into later releases failed. Other online searches seems to suggest that VS 2010 allows non-portable C++ code (on the topic of referencing rvalues) to be built. There is a semantic debate as to whether VS is a non-compliant compiler which builds all correct code, but allows extensions (so as to be non-portable).

Right now, I believe that g++ is giving the correct error, and VS (perhaps due to default config settings) is not.

I will check tomorrow if the /Za switch is set to "Disable Language Extensions" to see if I can force VS to give an error.
https://msdn.microsoft.com/en-us/library/0k0w269d.aspx
0
evilrixSenior Software Engineer (Avast)Commented:
Gcc is giving the correct error.  You cannot bind an rvalue to an lvalue reference. This is why rvalue references were introduced in C++11. VS2010 is wholly non-standard compliant. Later versions are better, but still take liberties.

If you can't use C++11 (better rethink this as C++14 will be the standard soon)  your only choice is to take a copy of the returned value. Since the object is designed to have reference semantics to the original array, this is perfectly correct, if slightly inefficient.
0
evilrixSenior Software Engineer (Avast)Commented:
>> I used to think I understood rvalue/lvalue in my C days a long time ago
Actually, there's nothing super magical about either.

lvalues are entities that may exist on the left (and right) hand side of an assignment.
rvalues may only appear on the right hand side of an assignment.

That's it. There is nothing else specifically prescribed to either. For example, an lvalue, by definition, can't be const but an rvalue doesn't have to be. The C++11 standard expands on these definitions and introduces xvalues, gvalues and pure rvalues, but these are just refinements of these two basic types.

My advise is to not worry too much about what lvalue or rvalue means, just remember that a temporary (and when a function returns by value it always creates a temporary*) can never be bound to a non-const C++03 style reference.

* The C++03 standard allows for Return Value Optimisation; however, the semantics of the result being an lvalue do not change. Further, C++11 introduced rvalue references, and by default temporary values are returned using move rather than copy semantics. Again, the result is still an rvalue!

>> evilrix, i hope you pardon me if i don't want to dive into the swamp of rvalue, lvalue, prvalue, xvalue
Truthfully, I don't blame you. The standard document can be hard to read and even harder to follow. It was written by very smart people to be a guide for compiler writers. It is the final point of call when arbitrating a confusion with the language but that doesn't mean it is the best place to go (at least, not unless you want you brain frazzled). I often find myself reading the same paragraph over and over and over and, each time, thinking it is telling me something different. Fortunately, on this particular subject I find it to be pretty clear (at least, I think I do - heh).
0
sarabandeCommented:
Gcc is giving the correct error.  
phoffric, if the c++ code you posted is from a Stroustrup book, then Stroustrup is not using gcc, obviously.

You cannot bind an rvalue to an lvalue reference.
if the temporary object returned from valarray operator[] is an rvalue, why statements like va[sl] *= 10; would compile? why does the reference for valarray at cplusplus.com state "valarray::operator[slice] returns a sub-array object, which has reference semantics to the original array, ready to be used as an l-value"? evilrix gave an answer to this when he explained "operators are also just functions". hence, assignment operators also are functions and therefore you also can use the return value as lvalue, like in 'va[sl] = 123;' since that could be expressed as 'va[sl].operator=(123);' on the other hand is "slice_array & x = va[sl];' invalid since it is an initialization and not a function. that means, when the temporary was used for an initialization or was passed by reference to another function, it turns to an rvalue (in its last modified state) and some compilers would have an error if you do so.

your only choice is to take a copy of the returned value.
since you can modifiy the returned object directly, a copy solves the issue and improves readability but is not the "only" way.

i tried to understand all the links and statements evilrix has posted regarding the rvalue status of a temporary. i think he is right that the current standard doesn't allow to make an alias (a reference variable) of a temporary returned by a function. the reason for this may be due to the factor that container elements may be "moved" rather than be copied such that the lifetime of the temporary must end with the current statement (and the initialization of an alias already is the next statement). i wonder though why a const reference still is valid until end-of-scope though of course manipulating the underlying valarray also could make those variables corrupt or point to wrong elements.

Sara
0
evilrixSenior Software Engineer (Avast)Commented:
It's returns an object with reference  semantics. Think of it as a smart pointer object but rather than having pointer semantic it has reference semantics. In other words, it returns an object by value but that object references the original array.
0
evilrixSenior Software Engineer (Avast)Commented:
A temporary bound to a reference has the same lifetime of the reference to which it is bound. Why?  Because that is that the standard prescribes.
0
phoffricAuthor Commented:
I have come to the conclusion that the VS 2010 Express and g++ compilers differ (at least in this singular case) because the default settings on VS 2010 Express are to allow MS extensions to the C++ library (boohiss). However, I believe that I have remedied this case by setting the /Za option to disable MS VS extensions (and for good measure, I negated the /Zc:wchar_t and /Zc:forScope, which also extends MS VS).

With this new configuration, the OP code in VS 2010 Express results in:
error C2440: 'initializing' : cannot convert from 'std::slice_array<_Ty>' to 'std::slice_array<_Ty> &'
A non-const reference may only be bound to an lvalue

Open in new window

How about that. It may actually be possible to write VS 2010 Express code that is compliant to the standard when using the /Za option.

Adding to the difficulties in learning to use valarray effectively, I am working only with g++ and Intel compilers for C++03 with some variations such as dynamic auto arrays on the stack (a capability that I will try to disable). In online searches, there are sometimes references to the specifications without identifying which flavor of C++ is being addressed.

Fortunately, some resources do indicate the flavors. For example, the following links shows that valarray has changed from C++98 to C++11 as can be seen with the explicit tabs for the two flavors.
   http://www.cplusplus.com/reference/valarray/valarray/operator%5B%5D/
   http://www.cplusplus.com/reference/valarray/slice_array/
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
phoffricAuthor Commented:
Thank you for your detailed responses.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.