C++ Most vexing parse when a number literal is the

2020-05-03 10:24发布

I was making a class that looked like this:

struct InputHandler
{
    std::vector<std::pair<int, int>> keyBindings( 256 );
};

It came up with an error, and I know this is because the compiler interprets this as a function instead of a constructor argument. But I was wondering is there anything ambiguous when I've passed a number literal in brackets such as in this case? I know I can fix this by just using curly brackets here, but I would have thought the most vexing parse issue wouldn't arise as using a number literal of 256 couldn't be interpreted as a function.

Edit: I'm happy to close or delete this question. The thing I learned is that even though that particular line isn't ambiguous, the general rules of C++11 forbid in-class initialisers with anything other than = or {}, this is as a general rule so as not to have an extra exception to the rule. On the other hand creating the vector in the main() function as:

std::vector<std::pair<int, int> foo(5);

Works fine. It's not an ambiguous expression, apparently.

2条回答
霸刀☆藐视天下
2楼-- · 2020-05-03 10:51

but I would have thought the most vexing parse issue wouldn't arise as using a number literal of 256 couldn't be interpreted as a function.

That is correct, it is not the most vexing parse. The most vexing parse is formally handled in [dcl.ambig.res]:

The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in [stmt.ambig] can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in [stmt.ambig], the resolution is to consider any construct that could possibly be a declaration a declaration.

The catch here is that you cannot initialize members using (), only = or {}, so naturally the ambiguity resolution does not apply.

查看更多
爷的心禁止访问
3楼-- · 2020-05-03 10:56

But I was wondering is there anything ambiguous when I've passed a number literal in brackets such as in this case?

Probably not, but it would have made the grammar more complex. Default member initializers were made to support only uniform initialization and copy initialization, because those things couldn't have appeared in existing code. And differentiating them from function declarations is easy.

Adding another overloaded usage for parentheses was never a goal. It's overused as is, IMO. If it's not supported in general, supporting it just for this particular use case you have in mind is hardly a useful feature that would merit the grammar contortions.

查看更多
登录 后发表回答