What is assignment via curly braces called? and can it be controlled?
That is not assignment. That is initialization.
Such initialization is allowed for aggregate only, that includes POD class. POD means Plain Old Data type.
Example,
//this struct is an aggregate (POD class)
struct point3D
{
int x;
int y;
int z;
};
//since point3D is an aggregate, so we can initialize it as
point3D p = {1,2,3};
See the above compiles fine : http://ideone.com/IXcSA
But again consider this:
//this struct is NOT an aggregate (non-POD class)
struct vector3D
{
int x;
int y;
int z;
vector3D(int, int, int){} //user-defined constructor!
};
//since vector3D is NOT an aggregate, so we CANNOT initialize it as
vector3D p = {1,2,3}; //error
The above does NOT compile. It gives this error:
prog.cpp:15: error: braces around initializer for non-aggregate type ‘vector3D’
See yourself : http://ideone.com/zO58c
What is the difference between point3D
and vector3D
? Just the vector3D
has user-defined constructor, and that makes it non-POD. Hence it cannot be initialized using curly braces!
What is an aggregate?
The Standard says in section §8.5.1/1,
An aggregate is an array or a class
(clause 9) with no user-declared
constructors (12.1), no private or
protected non-static data members
(clause 11), no base classes (clause
10), and no virtual functions (10.3).
And then it says in §8.5.1/2 that,
When an aggregate is initialized the
initializer can contain an
initializer-clause consisting of a
brace-enclosed, comma-separated list of
initializer-clauses for the members of
the aggregate, written in increasing
subscript or member order. If the
aggregate contains subaggregates, this
rule applies recursively to the
members of the subaggregate.
[Example:
struct A
{
int x;
struct B
{
int i;
int j;
} b;
} a = { 1, { 2, 3 } };
initializes a.x with 1, a.b.i with 2, a.b.j with 3. ]
what is a brace-or-equals initializer?
It's literally what it says on the tin: an initializer of the form = something
("equals") or { something }
("brace"). In other words, it excludes the ( something )
form of initializers.
The name comes from the grammar nonterminal for the construct.
What's the purpose of separate curly brackets in PHP
Its purpose is grouping operations for using in places where only one operation allowed.
if (cond) foo();
equals if (cond) { foo(); }
foo();
equals { foo(); }
C++ all differences between 'struct' and 'class'?
You can use {}
initializer for aggregates only1 and the first one is not an aggregate, as it has one private
data member.
The Standard says in section §8.5.1/1,
An aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members
(clause 11), no base classes (clause 10), and no virtual functions
(10.3).
1. Well, I meant, in C++03, you can use {}
for aggregates ONLY, but in C++11, you can use {}
even with non-aggregates (if the non-aggregate class is properly implemented to handle this).
Also see this for detail answer (on {}
initializer):
- What is assignment via curly braces called? and can it be controlled?
The semicolon inference doesn't work when an assignment statement is followed by curly braces in Scala?
Because it would be a legal call to apply
:
implicit class RichInt(i: Int) {
def apply(thunk: => Unit) = 33
}
val a = 1
{
val a = 2
println(a)
}
println(a) // 33 !
1 { ... }
is short for 1.apply {...}
. Now apply
is not defined for an Int
by default, but as the implicit enrichment shows, it is perfectly possible.
Edit: The semicolon inference conditions are described in '§1.2 Newline Characters' of the Scala Language Specification. The inferred semicolon is called 'special token "nl
"' in that text.
In general, three rules are given (summarised ex-negativo in this blog entry), and in your example they are all satisfied. The reason that the semicolon is still not inferred is given further down in the text.
The Scala grammar ... contains productions where optional
nl
tokens, but not semicolons, are accepted. This has the effect that a newline in one of these positions does not [!] terminate an expression or statement.
The relevant case of such an extra rule is the following:
A single new line token is accepted
– in front of an opening brace “{”, if that brace is a legal continuation of the current statement or expression ...
Example 1.2.2 shows the case of anonymous an subclass which I had referred to in the comment.
Conditional initialization in switch
1: Valid
case 1:
{
X x1;
break;
}
If it doesn't hit the condition, x1
can't be used by any further statements, so there can't be a runtime error with this. x1
doesn't try to exist outside braces.
2: Invalid
switch(i) {
case 1:
X x1; //don't break
i = 2;
...
...
...
case 2:
x1.someOperation()
}
In the above, if i
was 2
initially, you'd hit x1.someOperation()
before X x1
which would construct the object.
If it was allowed to compile, it would throw a runtime error or not, depending upon whether the case:1 was executed before 2, (and the object was constructed). Hence, it is disallowed by the compiler.
The same is allowed with Plain Old Data types which cannot have a user-defined constructor.
Related Topics
Was Not Declared in This Scope' Error
Why Can't I Initialize a Reference in an Initializer List with Uniform Initialization
Convert Char Array to Single Int
How Similar Are Boost.Filesystem and the C++ Standard Filesystem Library
When to Use Functors Over Lambdas
A Way in C++ to Hide a Specific Function
Linux Optimistic Malloc: Will New Always Throw When Out of Memory
What Is the Purpose of Ref-Qualified Member Functions
Std::Array with Aggregate Initialization on G++ Generates Huge Code
How to Use a Custom Type as Key for a Map in C++
Can Std::Vector Emplace_Back Copy Construct from an Element of the Vector Itself
When Is Explicit Move Needed for a Return Statement
Gcc -Wuninitialized/-Wmaybe-Uninitialized Issues
Cost of Throwing C++0X Exceptions
Why Does Constexpr Static Member (Of Type Class) Require a Definition
How to Resize a 2D Vector of Objects Given the Width and Height