Style: preferring parentheses to '=' for initialization?

N

Noah Roberts

Alf said:
* Noah Roberts:

Assuming you're asking where would one use an explicit default
constructor call, e.g. like

foo( std::string() + "Akka bakka " + someCString + "bonka rakka!" );

Ok, duh...I'm dumb.
 
L

Luke Meyers

Howard said:
template <class T>
void swap(T& x, T& y)
{
T tmp = x;
x = y;
y = tmp;
}

as coded above this requires T to have a *non-explicit* copy
constructor. But:

template <class T>
void swap(T& x, T& y)
{
T tmp(x);
x = y;
y = tmp;
}

will work with a T with an explicit copy constructor. (I'm still trying
to figure out why anyone would *want* an explicit copy constructor).

To aggressively enforce their preference for the initialization style
under discussion, I suppose.

Luke
 
J

Jerry Coffin

[ ... ]
That's entirely just a perspective, a point of view, a way of looking at
things. Many more people would say, "It's a member function whose name is
identical to that of the class."

The standard ($12.1/1) says: "Constructors do not have
names."

Victor's statement is clearly more than "just a
perspective" -- it's _fact_.

The "many more people" you mention would clearly just be
plain wrong.

This is NOT a distinction without a difference either --
it becomes quite important under some circumstances. For
one example, since a ctor does not have a name, it can
never be found during name lookup.
Does the Standard make a distinction between a "call" and an
"invocation"? If it does, I wasn't aware of it, but I'll be more than
happy to change my use of language from here on in if so.

The standard doesn't seem to try to distinguish between
"call" and "invoke", but it very clearly distinguishes
between calling a function, and taking some action that
will (indirectly) call the function to be called.

For example, in discussing how ctors are called, the
standard says: "...an explicit type conversion using the
functional notation (5.2.3) will cause a constructor to
be called to initialize an object."
Oh... I think I finally understand the crux of this argument -- are you
basing your stance on the distinction between a "call" and an
"invocation"?

No -- on the difference between directly calling
something, and taking an action that indirectly causes it
to be called.

You don't call a constructor -- ever. You can't. It
doesn't have a name, so there's no way for its name to be
looked up, so there's no way for you to call it.

Your example using placement new did have a some point --
it's certainly true that placement new comes closer to
isolating the ctor call itself from other things, most
obviously allocating memory for the object.

Nonetheless, you're still not calling the ctor -- you're
still just taking an action that indirectly causes the
ctor to be called. In reality, the compiler often has to
generate extra "stuff" associated with doing construction
over and above a call to the ctor itself.

Consider one obvious example:

struct Y {
int val;

Y(int init) :val(init) {}
virtual ~Y() { std::cout << "~Y\n"; }
};

struct A {
A() {}
virtual ~A() {}
};

strut Z {
int val;
Z(int init) :val(init) { throw 1; }
};

class X : public Y {
A a;
Z z;
X(int a, int b) : Y(a), z(b) {}
};

Now, when you attempt to construct an object of class X,
even using placement new, the compiler has to do _quite_
a bit more than just call X's ctor. It has to arrange for
the ctors for A, Z, Y and X to be called (in the correct
order). Since Z's ctor turns out to throw an exception,
it also has to include code to catch the exception and
invoke the destructors for A and Y as well, and then re-
thrown the exception.

To summarize: no, you don't a ctor -- ever. There are a
number of things you can do that will cause ctors to be
called, but it's always done indirectly. Depending on the
classes involved, chances are that constructing an object
involves _quite_ a bit more than just calling its
constructor -- and while placement new removes one of the
other things that otherwise happens, it can still leave
quite a bit more than has to be done.
 
A

Alf P. Steinbach

* Jerry Coffin:
You don't call a constructor -- ever. You can't.
Wrong.


It doesn't have a name, so there's no way for its name to be
looked up,
Right.


so there's no way for you to call it.
Wrong.


....
Now, when you attempt to construct an object of class X,
even using placement new, the compiler has to do _quite_
a bit more than just call X's ctor.

Note that also for calls of virtual functions, more goes on than with a
non-virtual function.

We still call the calls calls.

Anyway, the argument is silly: it is a restriction of what something
undefined that you choose to call a "call" could be, to the point that
that undefined thing can't be anything relevant, and so, with a bit of
circular reasoning, the compiler has to do quite a bit more than that.

Cheers,

- Alf
 
T

Tomás

Alf P. Steinbach posted:
Assuming you're asking where would one use an explicit default
constructor call, e.g. like

foo( std::string() + "Akka bakka " + someCString + "bonka rakka!" );


But we all know that the following would be favourable:

foo( std::string("Akka bakka ") + someCString + "bonka rakka!" );


-Tomás
 
A

Alf P. Steinbach

* Tomás:
Alf P. Steinbach posted:



But we all know that the following would be favourable:

foo( std::string("Akka bakka ") + someCString + "bonka rakka!" );

Well no, I don't know that. ;-)
 
T

Tomás

Alf P. Steinbach posted:
* Tomás:

Well no, I don't know that. ;-)


I just get this itch when I know something could be improved upon (even
when I know full well that the original poster knew what he/she was
doing!). I'm sure Victor would hate to see a "newbie" read your code and
then reproduce it. : )

-Tomás
 
N

Noah Roberts

Tomás said:
Alf P. Steinbach posted:



I just get this itch when I know something could be improved upon (even
when I know full well that the original poster knew what he/she was
doing!). I'm sure Victor would hate to see a "newbie" read your code and
then reproduce it. : )

I don't imagine there being a whole lot of difference between the two
versions. The have the same amount of temporaries, they call append
operation the same amount of times and with the same data...I just
really doubt there is any pragmatic difference between the two and if
there is it certainly isn't certain. For instance, a string could
easily be implemented in terms of:

string(const char * x) : whatever goes here to build a string... {
append(x); }

operator+(T t) { append(t); }

It couldn't just copy the pointer...if it where done that way, and that
is the most obvious, then it wouldn't matter if you did string() +
"xyz" or string("xyz").
 
T

Tomás

Noah Roberts posted:

It couldn't just copy the pointer...if it where done that way, and
that is the most obvious, then it wouldn't matter if you did string()
+ "xyz" or string("xyz").


I'd advocate the style more than anything else, just as how I'd always
advocate:

SomeClass object(something);

instead of:

SomeClass object;
object = something;


Initialise wherever possible. If you can't, then assign.


-Tomás
 
A

Alf P. Steinbach

* Tomás:
Noah Roberts posted:



I'd advocate the style more than anything else, just as how I'd always
advocate:

SomeClass object(something);

instead of:

SomeClass object;
object = something;


Initialise wherever possible. If you can't, then assign.

For string expressions it doesn't much matter.

Consider readability and, not the least, writeability:

throwX( STR __funcname__ + ": " + errorMessage );

throwX( std::string( __funcname__ ) + ": " + errorMessage );

I haven't actually done that, but now that I thought of it I think it
could be worth checking whether the OS API headers (which abound in
macros) define a macro STR: if not, then it could be very useful... :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,147
Latest member
CarenSchni
Top