0

I know that the following, if possible, would be an absolutely bad practice, but I want to know if this is possible.

The question is the following: is it possible in C++ (and in a way the compiler does not throw any warning), to perform a useless arithmetic operation with a function returning a void.

std::vector<int> v;
int i = 42 + v.resize(42); 
/* How to transform the last line to execute resize and to have i = 42 */

I know that this is stupid, but that is not the question...

Vincent
  • 57,703
  • 61
  • 205
  • 388

4 Answers4

6

I'm not sure it makes much sense, but you could use the comma operator here:

int i = (v.resize(42), 42);
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 2
    There possibly are good reasons `,` to use the comma operator `,` but this is not `,` one `,` of `,` them. – Yakk - Adam Nevraumont Feb 19 '14 at 19:03
  • @Yakk: Why do you this it is not a good use case for the comma operator (imagine this being inside a template, or a macro, or some generated C++ code)? Of course as handwritten code it is awful since not very readable. – Basile Starynkevitch Feb 19 '14 at 19:45
  • In a template, do it in more than one line -- there are no limits there. In a macro, call a function. In generated code, call a function. In both generated code and macros, you can have helper stuff far away from the point of use, like: `template std::size_t set_container_size( C& c, std::size_t s ) { c.resize(s); return s; }`, then `int i = set_container_size(v, 42);` *in the macro* or generated code. An example of "good" uses: `for` limitations (increment two variables) and pre-C++1y `constexpr` gymnastics. – Yakk - Adam Nevraumont Feb 19 '14 at 19:59
5

You could use the comma operator:

int i = (v.resize(42), 42);

and with GCC you could use its statement expression extension:

int i = ({v.resize(42); 42;})

and in standard C++11 you could use and call an anonymous closure:

int i = ([&v]() {v.resize(42); return 42;}());
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
2

Type void has no values so it may not be used in arithmetic expressions.

In my opinion the design of member function resize is bad. Instead of voidit should return the object itself. In this case you could write for example

int i = v.resize(42).size(); 

I pointed out about this in the forum where the C++ Standard is discussed.

As for your question then you can write

int i = ( v.resize(42), v.size() );

using the comma operator.

Or maybe it would be better to separate these two calls

v.resize(42);
int i = v.size();
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

Don't see the point, but here's another way

std::tie(i, std::ignore) = std::make_tuple(42, (v.resize(42),1) );

Also you can do:

if ((i=42)) v.resize(42); 

And don't forget

do { v.resize(42); } while (!(i=42)); 

And the favorite

(i=42) ? v.resize(42) : i;

Or (the only serious c++ in the post)

int i(0);
std::vector<int> v(i=42);

Come on, this has no end

.....

Nikos Athanasiou
  • 29,616
  • 15
  • 87
  • 153