question about A a = b? f1(x,y,z) : f2(o,p,q);

  • Thread starter 胡宇光
  • Start date
È

胡宇光

Think about the following code:

void func() {
...
A a = b? f1(x,y,z):f2(o,p,q);
...
}

1, class A doesn't not have default constructor.

2, x,y,z,o,p,q and the f1,f2 name are very long.

How can I make the code shorter?

If 1x is allowed, maybe I can write

auto F1 = [&]() {return f1(x,y,z);}
auto F2 = [&]() {return f2(o,p,q);}
A a = b? F1():F2();

If use c++ 03, how can I make the code shorter?
 
V

Victor Bazarov

Think about the following code:

void func() {
...
A a = b? f1(x,y,z):f2(o,p,q);
...
}

1, class A doesn't not have default constructor.

2, x,y,z,o,p,q and the f1,f2 name are very long.

If one character names are "very long", perhaps there is some other help
required to the reader of the code.
How can I make the code shorter?

If 1x is allowed, maybe I can write

auto F1 = [&]() {return f1(x,y,z);}
auto F2 = [&]() {return f2(o,p,q);}
A a = b? F1():F2();

Is that shorter? I don't think so. You just introduced two 'auto',
names 'F1' and 'F2', other symbols to define them. How is it shorter
than calling 'f1' and 'f2' directly?
If use c++ 03, how can I make the code shorter?

You can't, really. Anything you do will be introduction of additional
code. Remove the spaces and you can shorten the code by 3 characters.

If class 'A' doesn't have a copy constructor and 'f1' and 'f2' return
some other type, then you *have to* use this form:

A a(b? f1(x,y,z):f2(o,p,q));

It's not shorter than

A a=b? ...

it has slightly different semantics.

V
 
S

Stefan van Kessel

If class 'A' doesn't have a copy constructor and 'f1' and 'f2' return
some other type, then you *have to* use this form:

A a(b? f1(x,y,z):f2(o,p,q));


Not necessarily. For example if A is constructable from the common type
of the return types of f1 and f2 and either the common type isn't a
built-in type or that constructor isn't explicit, then

A a(b? f1(x,y,z):f2(o,p,q));
and
A a = (b? f1(x,y,z):f2(o,p,q));

should both work.

For copy initialization (i.e. T x = y;) to work, T doesn't generally
have to have a copy constructor or assignment operator.
 
S

Stefan van Kessel

Think about the following code:

void func() {
...
A a = b? f1(x,y,z):f2(o,p,q);
...
}

1, class A doesn't not have default constructor.

2, x,y,z,o,p,q and the f1,f2 name are very long.

How can I make the code shorter?

If 1x is allowed, maybe I can write

auto F1 = [&]() {return f1(x,y,z);}
auto F2 = [&]() {return f2(o,p,q);}
A a = b? F1():F2();

If use c++ 03, how can I make the code shorter?


I assume you just want the
A a = b? f1(x,y,z):f2(o,p,q);
statement to be shorter / more readable, not the entire code.

If so, you could try the following:

const A& a1 = f1(x,y,z);
const A& a2 = f2(o,p,q);
A a = b?a1:a2;

If you haven't come across const references to temporaries before, you
may want to take a look at
http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
 
S

Stefan van Kessel

I assume you just want the
A a = b? f1(x,y,z):f2(o,p,q);
statement to be shorter / more readable, not the entire code.

If so, you could try the following:

const A& a1 = f1(x,y,z);
const A& a2 = f2(o,p,q);
A a = b?a1:a2;

One caveat I forgot: with that code both f1 and f2 will actually be
called. So if performance matters, that's not a good alternative to your
code, where only either f1 or f2 will be called.
 
V

Victor Bazarov

If class 'A' doesn't have a copy constructor and 'f1' and 'f2' return
some other type, then you *have to* use this form:

A a(b? f1(x,y,z):f2(o,p,q));


Not necessarily. For example if A is constructable from the common type
of the return types of f1 and f2 and either the common type isn't a
built-in type or that constructor isn't explicit, then

A a(b? f1(x,y,z):f2(o,p,q));
and
A a = (b? f1(x,y,z):f2(o,p,q));

should both work.

For copy initialization (i.e. T x = y;) to work, T doesn't generally
have to have a copy constructor or assignment operator.


I believe you're mistaken in this. Here is the code I was thinking of:

struct A
{
double d_;
A(double d) : d_(d) {}

private:
A(const A&);
};

int f1(int x, int y, int z) { return 42; }
unsigned f2(unsigned p, unsigned o, unsigned q) { return 666; }

double foo(bool b)
{
A a = b? f1(1,2,3):f2(1,2,3); // error - copy c-tor private

return a.d_;
}

V
 
S

Stefan van Kessel

I believe you're mistaken in this. Here is the code I was thinking of:

struct A
{
double d_;
A(double d) : d_(d) {}

private:
A(const A&);
};

int f1(int x, int y, int z) { return 42; }
unsigned f2(unsigned p, unsigned o, unsigned q) { return 666; }

double foo(bool b)
{
A a = b? f1(1,2,3):f2(1,2,3); // error - copy c-tor private

return a.d_;
}

You're right, I apologize. MSVC compiles it without warning per default,
so I incorrectly assumed that it's valid code. But it is a nonstandard
extension of MSVC.

For copy initialization the type does have to be copy constructable. The
copy constructor won't necessarily be called but it has to be available.
 
J

Juha Nieminen

Victor Bazarov said:
auto F1 = [&]() {return f1(x,y,z);}
auto F2 = [&]() {return f2(o,p,q);}
A a = b? F1():F2();

Is that shorter? I don't think so. You just introduced two 'auto',
names 'F1' and 'F2', other symbols to define them. How is it shorter
than calling 'f1' and 'f2' directly?

I don't think the point is it being shorter, but clearer.

Sometimes it's better to use additional variables even though they might
not be strictly mandatory, in order to make the code clearer and easier
to read.

In the above case I would prefer using references to the return values
of f1() and f2() rather than using lambdas.
 
V

Victor Bazarov

Victor Bazarov said:
auto F1 = [&]() {return f1(x,y,z);}
auto F2 = [&]() {return f2(o,p,q);}
A a = b? F1():F2();

Is that shorter? I don't think so. You just introduced two 'auto',
names 'F1' and 'F2', other symbols to define them. How is it shorter
than calling 'f1' and 'f2' directly?

I don't think the point is it being shorter, but clearer.

Clarity (like readability) is in the eye of the beholder. Since the use
of the argument list is now removed from the place where it matters, the
clarity is reduced, IMNSHO.
Sometimes it's better to use additional variables even though they might
not be strictly mandatory, in order to make the code clearer and easier
to read.

In that case the names of the variables (F1 vs f1 and F2 vs f2) does not
seem to present any advantage in terms of clarity. Again, that's just
my opinion, since clarity is not a universal trait.
In the above case I would prefer using references to the return values
of f1() and f2() rather than using lambdas.

.... which has different semantics as already has been mentioned.

V
 
S

Stuart

On 10/12/12 Drew Lawson wrote:
[snip]
Longer lines that I personally prefer. Another try:

A a = crypticDecidingFactor ? glorbifyWithFobnitzCorrection(hexDigitsPerProductID,
historicalPriceTeaInChinaIn2008Euros,
jennysPhoneNumber)
: frobnitzicateWithGlorbAdjustment(lolcatsPerCatLady,
temperatureEarlGrayHot22ndCentury,
until12thOfNever);

That's not great, but it is less painful to my eyes to read.
(And it strongly calls out for some comments explaining what is happening.)

LOL, reading that was quite fun.

Where did you get these names from? I expect that a 100 years from now
people will no longer use "foo" or "bar" as example names, but
"glorbify" and "frobnitzicate". The last one made me laugh so hard that
I was glad that I was already sitting on the toilet at the time ...

Regards,
Stuart
 
J

Juha Nieminen

Victor Bazarov said:
In that case the names of the variables (F1 vs f1 and F2 vs f2) does not
seem to present any advantage in terms of clarity. Again, that's just
my opinion, since clarity is not a universal trait.

It was example code. The names are ostensibly not that non-telling in
the original code.
 
P

Pavel

胡宇光 said:
Think about the following code:

void func() {
...
A a = b? f1(x,y,z):f2(o,p,q);
...
}

1, class A doesn't not have default constructor.

2, x,y,z,o,p,q and the f1,f2 name are very long.

How can I make the code shorter?

If 1x is allowed, maybe I can write

auto F1 = [&]() {return f1(x,y,z);}
auto F2 = [&]() {return f2(o,p,q);}
A a = b? F1():F2();

If use c++ 03, how can I make the code shorter?
try (using RVO it should be equivalent):
namespace /* if not in the header */ {
A
createA(bool b, XP x, YP y, ZP z, OP o, PP p, QQ p) {
if (b)
return f1(x, y, z);
return f2(o, p, q);
}
}

void
func() {
...
A a(createA(b, x, y, z, o, p, q));
...
}

Above, [X-ZO-Q]P) are the names of the hand-selected best parameter type to pass
in x..q, respectively.

The savings are long f1, f2; also the parameter names in createA can be quite
short; also, it would be easier to debug f1 and f2 branches if you use a basic
debugger.

HTH
-Pavel
 
È

胡宇光

在 2012å¹´10月11日星期四UTC+8下åˆ11æ—¶57分17秒,Stefan van Kessel写é“:
Think about the following code:
void func() {

A a = b? f1(x,y,z):f2(o,p,q);

1, class A doesn't not have default constructor.
2, x,y,z,o,p,q and the f1,f2 name are very long.
How can I make the code shorter?
If 1x is allowed, maybe I can write
auto F1 = [&]() {return f1(x,y,z);}
auto F2 = [&]() {return f2(o,p,q);}
A a = b? F1():F2();

If use c++ 03, how can I make the code shorter?





I assume you just want the

A a = b? f1(x,y,z):f2(o,p,q);

statement to be shorter / more readable, not the entire code.



If so, you could try the following:



const A& a1 = f1(x,y,z);

const A& a2 = f2(o,p,q);

A a = b?a1:a2;



If you haven't come across const references to temporaries before, you

may want to take a look at

http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

const& a1 = f1(x,y,z)
const& a2 = f2(o,p,q)
it's diff with the A a = b? f1():f2().
The original code just execute one function, not both.
 

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,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top