Since this question is tagged language-lawyer, the direct answer is that, from [stmt.ambig]:
There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (
. In those cases the statement is a declaration.
And, similarly, for functions, 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.
Hence:
Why oh why is std::string("foo")
so different from std::string(foo)
The former cannot be a declaration. The latter can be a declaration, with a redundant set of parentheses. Thus, the former isn't a declaration and the latter is.
The underlying issue is that, grammaticaly, declarators can start with a (
which could make it indistinguishable from a function-style explicit type conversion. Rather than come up with arbitrary complex rules to try to determine what the user meant, the language just picks one, and it's easy enough for the user to fix the code to actually do what he meant.
x
is already defined,int(x)
is type cast but if it's not defined,int(x)
is a variable declaration. Seriosly, what the hell? – Dierdrestd::unique_lock(m_mutex);
So I can't not think about it. – Dierdrestd::unique_lock(m_mutex);
" That's something completely different. Do you know what you're actually talkng about? "Seriously, what the hell" is context dependent and you should know how to eplore the context dude! – Violistunique_lock
named 'm_mutex'. It doesn't lock anything. It works becauseunique_lock
has ctor with no arguments. Am I wrong? – Dierdreunique_lock
has ctor with no arguments." Though that's not a language deficiency, but a debatable question whystd::unique_lock
provides a default constructor at all. – Violiststd::unique_lock(m_mutex)
actually will work fine -std::unique_lock<std::mutex>(m_mutex)
is the situation you're talking about. – Derinastd::unique_lock(m_mutex);
would bestd::unique_lock m_mutex
, which is ill-formed because class template argument deduction fails. So, you'll get a compiler error (which is what I meant by "fine" - as in, it wont' do the wrong thing) – Derina