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

Casting needed when comparing using brace initialization

51 views
Skip to first unread message

Paul

unread,
Sep 30, 2015, 4:38:11 AM9/30/15
to
In the code below, why isn't {3,4} recognized immediately as a vector<int>?
Why does it fail to compile if I replace if(vec == std::vector<int>({3,4})) by if(vec == {3,4}) ?

Many thanks for your help.

Paul


void printVectorIfSpecial(const std::vector<int>& vec)
{
if(vec == std::vector<int>({3,4}))
{
// do something
}

}

bartekltg

unread,
Sep 30, 2015, 8:22:45 AM9/30/15
to
There is no type (of the class) deduction based on a constructor.
And this is the main reason, why we have a _function_ make_pair.
pair {1,2} do not work.
Either pair<int> {1,2} or make_pair(1,2)

bartekltg


bartekltg

unread,
Sep 30, 2015, 8:27:18 AM9/30/15
to
OK, this is wrong answer. A correct one, but for different
question ;-)

{1,2,3} is an iniclializer list, not a vector.
vector i c++ is just z class, not a spacjal type in language.
You can not use vector in you program (but why you would;))
and {1,2} still is the same.

bartekltg


Martin Shobe

unread,
Sep 30, 2015, 8:58:34 AM9/30/15
to
On 9/30/2015 3:37 AM, Paul wrote:
> In the code below, why isn't {3,4} recognized immediately as a vector<int>?

Because it's not a vector, it's an initializer list.

> Why does it fail to compile if I replace if(vec == std::vector<int>({3,4})) by if(vec == {3,4}) ?

Because there's no equality operator defined for vectors and initializer
lists.

> void printVectorIfSpecial(const std::vector<int>& vec)
> {
> if(vec == std::vector<int>({3,4}))
> {
> // do something
> }
>
> }

Martin Shobe

Ben Bacarisse

unread,
Sep 30, 2015, 9:19:02 AM9/30/15
to
Paul <peps...@gmail.com> writes:

> In the code below, why isn't {3,4} recognized immediately as a
> vector<int>?

The main problem is this one:

> Why does it fail to compile if I replace if(vec ==
> std::vector<int>({3,4})) by if(vec == {3,4}) ?

It fails to compiler because it's not syntactically valid -- the {...}
form is an initialiser list and that just can't occur in that position.
An IL is not a valid primary expression.

So your questions are really why does C++ not permit an IL to be a
primary expression, and, if C++ did permit it, would it be able to find
the correct operator== function to call?

I can't give you a good answer to either question. I suspect that
making ILs into primary expressions would introduce a vast rats nest of
complications, but that's not much more than a guess.

<snip>
--
Ben.

Paul

unread,
Sep 30, 2015, 9:48:23 AM9/30/15
to
Thanks, Ben and everyone else. My posting was in no sense intended as a "Why doesn't C++ allow...?" type of question. I didn't know why I got the error and was trying to avoid similar problems in future. So, suppose that I want code which says "do something if the vec is {3, 4}" Is my code (which works) best practice, or should I avoid casting? If so, how?

Many thanks for your help,

Paul

Alf P. Steinbach

unread,
Sep 30, 2015, 12:45:15 PM9/30/15
to
On 9/30/2015 10:37 AM, Paul wrote:
> In the code below, why isn't {3,4} recognized immediately as a vector<int>?
> Why does it fail to compile if I replace
>
> if(vec == std::vector<int>({3,4}))
>
> by
>
> if(vec == {3,4}) ?
>
> void printVectorIfSpecial(const std::vector<int>& vec)
> {
> if(vec == std::vector<int>({3,4}))
> {
> // do something
> }
>
> }

I'm not sure. Possibly due to pure grammar issues. Consider that the
following works as intended:

<code>
#include <assert.h>
#include <vector>
#include <stdio.h>

void printVectorIfSpecial(const std::vector<int>& vec)
{
if( operator==( vec, {3,4} ) )
{
assert( vec.size() == 2 ); // Doesn't trigger: size is 2.
printf( "{3,4}.size() = %d.\n", int( vec.size() ) );
}
}

auto main() -> int
{
printVectorIfSpecial( std::vector<int>{3,4} );
}
</code>

The assert is just about the possibility that without knowing exactly
what it does, {3,4} /could/ be invoking the 2-argument vector
constructor that would create a vector of 4 items, each of value 3.

But given that the code works, it's hard (for me) to say why your
original isn't permitted.


Cheers, & sorry if that doesn't really help, but,

- Alf

Ben Bacarisse

unread,
Sep 30, 2015, 2:11:52 PM9/30/15
to
With Alf's answer you have the full picture: the direct comparison is
not permitted for grammatical reasons, but you can do what you want (in
this case at least) by writing the operator== function call directly.

A function call's arguments (in C++11) may include a number of brace
enclosed initializer clauses, but these are not permitted on either side
of an equality operator.

--
Ben.

Gareth Owen

unread,
Sep 30, 2015, 2:21:35 PM9/30/15
to
Paul <peps...@gmail.com> writes:

> Thanks, Ben and everyone else. My posting was in no sense intended as
> a "Why doesn't C++ allow...?" type of question. I didn't know why I
> got the error and was trying to avoid similar problems in future. So,
> suppose that I want code which says "do something if the vec is {3,
> 4}" Is my code (which works) best practice, or should I avoid casting?

I think partly your difficulty lies in thinking of

std::vector<int>({3,4})

as a cast. It really isn't, it's actually constructing a whole new
object and initialising it with the values.

By analogy, your code is more like:

if(v == std::vector<int>(19,7)) {
// do something if v is a 19 element vector of '7's.
}

So, you might use a const local at function or file scope

namespace{
const std::vector meaningful_name({3,4});
}

int myfunc(void)
{
// or maybe
static const std::vector alternative_meaningful_name({3,4});

if(v == meaningful_name){
// ...
}
}

0 new messages