473,387 Members | 3,810 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

What is a good idiom for handling a lazy object?

What is a good idiom for handling a lazy object? I see 2 good
possibilities. Any more, any comments? Which way do people here use?
(1)

class Thing {
public:
Thing(double x, double y) : x(x), y(y), calculated(false) { }
double operator()() const {
if (!calculated) calculate();
return z;
}
private:
double x;
double y;
mutable bool calculated;
mutable double z;
void calculate() { z = x+y; }
};
(2)

class Answer {
virtual ~Answer();
};

class Lazy : public Answer {
public:
Lazy(double x, double y) : x(x), y(y) { }
private:
friend class Eval;
double x;
double y;
};

class Eval : public Answer {
public:
Eval(const Lazy& lazy) : z(calculate(lazy))
double operator()() const { return z; }
private:
double z;
static void calculate(const Lazy& lazy) { return lazy.x+lazy.y; }
};

class Thing {
public:
Thing(double x, double y) : answer(new Lazy(x, y)) { }
double operator()() const {
const Lazy * lazy = dynamic_cast<const Lazy *>(answer.get());
if (lazy) {
answer.reset(new Eval(*lazy));
}
const Eval * eval = static_cast<const Eval *>(answer.get());
assert(eval);
return (*eval)();
}
private:
mutable boost::shared_ptr<Answer> answer;
};
Jul 22 '05 #1
12 2770
Siemel Naran wrote:
What is a good idiom for handling a lazy object? I see 2 good
possibilities. Any more, any comments? Which way do people here use?
(1)

class Thing {
public:
Thing(double x, double y) : x(x), y(y), calculated(false) { }
double operator()() const {
if (!calculated) calculate();
return z;
}
private:
double x;
double y;
mutable bool calculated;
mutable double z;
void calculate() { z = x+y; }
};
(2)

class Answer {
virtual ~Answer();
};

class Lazy : public Answer {
public:
Lazy(double x, double y) : x(x), y(y) { }
private:
friend class Eval;
double x;
double y;
};

class Eval : public Answer {
public:
Eval(const Lazy& lazy) : z(calculate(lazy))
double operator()() const { return z; }
private:
double z;
static void calculate(const Lazy& lazy) { return lazy.x+lazy.y; }
};

class Thing {
public:
Thing(double x, double y) : answer(new Lazy(x, y)) { }
double operator()() const {
const Lazy * lazy = dynamic_cast<const Lazy *>(answer.get());
if (lazy) {
answer.reset(new Eval(*lazy));
}
const Eval * eval = static_cast<const Eval *>(answer.get());
assert(eval);
return (*eval)();
}
private:
mutable boost::shared_ptr<Answer> answer;
};


I just want to acknowledge having looked at this post. I this is a good
question, but my requier a bit more background. I did a google on lazy
object, and found this: http://c2.com/cgi/wiki?LazyObject

I know Stroustrup covers something similar to this in TC++PL(SE), I hope to
be able to revisit the topic soon. It would probably help me evaluate your
code if you explained just a bit more in your own words what your design
objectives are.
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #2
"Siemel Naran" <Si*********@REMOVE.att.net> wrote...
What is a good idiom for handling a lazy object? I see 2 good
possibilities. Any more, any comments? Which way do people here use?
(1)

class Thing {
public:
Thing(double x, double y) : x(x), y(y), calculated(false) { }
double operator()() const {
if (!calculated) calculate();
return z;
}
private:
double x;
double y;
mutable bool calculated;
mutable double z;
void calculate() { z = x+y; }
void calculate() const { z = x+y; calculated = true; }
};
(2)

class Answer {
virtual ~Answer();
};

class Lazy : public Answer {
public:
Lazy(double x, double y) : x(x), y(y) { }
private:
friend class Eval;
double x;
double y;
};

class Eval : public Answer {
public:
Eval(const Lazy& lazy) : z(calculate(lazy))
double operator()() const { return z; }
private:
double z;
static void calculate(const Lazy& lazy) { return lazy.x+lazy.y; }
};

class Thing {
public:
Thing(double x, double y) : answer(new Lazy(x, y)) { }
double operator()() const {
const Lazy * lazy = dynamic_cast<const Lazy *>(answer.get());
if (lazy) {
answer.reset(new Eval(*lazy));
}
const Eval * eval = static_cast<const Eval *>(answer.get());
assert(eval);
return (*eval)();
}
private:
mutable boost::shared_ptr<Answer> answer;
};


I am not sure why you need to make such a long way around it. Besides,
I was always told that if you need to use dynamic_cast, you should re-
approach your design, it may have too many interdependencies.

Victor
Jul 22 '05 #3
"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message news:28-
I just want to acknowledge having looked at this post. I this is a good
question, but my requier a bit more background. I did a google on lazy
object, and found this: http://c2.com/cgi/wiki?LazyObject
Right, that describes it well.
I know Stroustrup covers something similar to this in TC++PL(SE), I hope to be able to revisit the topic soon. It would probably help me evaluate your
code if you explained just a bit more in your own words what your design
objectives are.


I have created a Select object. Option 1 is for the constructor to open the
SQL connection, run the query, etc. Option 2 is for the constructor to just
store the function argument parameters. Only when we start iterating with
Select::for_each or whatever, then open the connection, do the query, etc.
This way we only open the connection when we really need it. Also, we
mininimize the number of connections, because we don't want temporary Select
objects such as those returned from functions to open a connection.

As another example I have written,

class Income
{
public:
...

double total() const
{
if (!m_hastotal)
{
m_total=
d_salary
+d_interest+d_dividends
+d_shortterm+d_longterm
;
m_hastotal=true;
}
return m_total;
}
private:
double d_salary;
double d_interest;
double d_dividends;
double d_shortterm;
double d_longterm;
mutable bool m_hastotal;
mutable double m_total;
This way a second call to income.total() doesn't have to do any
calculations. Not that adding 5 doubles is a big deal anyway, but I was
just playing around here.
Jul 22 '05 #4
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:p2Hec.123685$K91.338613@attbi_s02...
"Siemel Naran" <Si*********@REMOVE.att.net> wrote...

What is a good idiom for handling a lazy object? I see 2 good
possibilities. Any more, any comments? Which way do people here use?
(1)

class Thing {
public:
Thing(double x, double y) : x(x), y(y), calculated(false) { }
double operator()() const {
if (!calculated) calculate();
return z;
}
private:
double x;
double y;
mutable bool calculated;
mutable double z;
void calculate() { z = x+y; }


void calculate() const { z = x+y; calculated = true; }


Thanks, good catch!
};
(2)

class Answer {
virtual ~Answer();
};

class Lazy : public Answer {
public:
Lazy(double x, double y) : x(x), y(y) { }
private:
friend class Eval;
double x;
double y;
};

class Eval : public Answer {
public:
Eval(const Lazy& lazy) : z(calculate(lazy))
double operator()() const { return z; }
private:
double z;
static void calculate(const Lazy& lazy) { return lazy.x+lazy.y; }
};

class Thing {
public:
Thing(double x, double y) : answer(new Lazy(x, y)) { }
double operator()() const {
const Lazy * lazy = dynamic_cast<const Lazy *>(answer.get());
if (lazy) {
answer.reset(new Eval(*lazy));
}
const Eval * eval = static_cast<const Eval *>(answer.get());
assert(eval);
return (*eval)();
}
private:
mutable boost::shared_ptr<Answer> answer;
};


I am not sure why you need to make such a long way around it. Besides,
I was always told that if you need to use dynamic_cast, you should re-
approach your design, it may have too many interdependencies.


The second way seems good for complex objects as we construct a whole new
object like Eval whose constructor garauntees all parts of the objects (the
private member variables) are initialized properly. Using the 1st way means
we have a super-class with all the variables (to store the lazy parameters x
and y, as well as the result variables), and it seems fine for simple
classes like my Income example in the other post and the class above. For
more complex classes the 2nd way forces the use of a constructor, which is a
nice way to fully initialize an object.

And yes, the use of dynamic_cast is a little bothersome, but it's really
just an if statement. I think it's OK in this context because class Thing
knows about the existence of class Lazy and Eval, and these are probably all
in one cpp file.
Jul 22 '05 #5
Siemel Naran wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:p2Hec.123685$K91.338613@attbi_s02...
"Siemel Naran" <Si*********@REMOVE.att.net> wrote...
void calculate() const { z = x+y; calculated = true; }


Thanks, good catch!


Yup. That had me a bit confused.
> (2)
>
> class Answer {
> virtual ~Answer();
> };
Just tracing this through out loud:

Answer doesn't look like a very useful class. I assume you are creating it
to share acommon type, and, in particular the same descructor.
> class Lazy : public Answer {
> public:
> Lazy(double x, double y) : x(x), y(y) { }
> private:
> friend class Eval;
> double x;
> double y;
> };
You've exposed Lazy::x and Lazy::y to Eval.
> class Eval : public Answer {
> public:
> Eval(const Lazy& lazy) : z(calculate(lazy))
I believe you meant to put a semicolon at the end of the above line. No?
> double operator()() const { return z; } This returns Eval::z no matter what. No magic involved, right?
> private:
> double z;
> static void calculate(const Lazy& lazy) { return lazy.x+lazy.y; }
This doesn't make sense to me. You seem to be returning a value in a
function whose return type is void.

I believe you /can/ access lazy.x and lazy.y because of the friendship
relationship;
> }; > class Thing {
> public:
> Thing(double x, double y) : answer(new Lazy(x, y)) { }
> double operator()() const {
> const Lazy * lazy = dynamic_cast<const Lazy *>(answer.get());
> if (lazy) {
> answer.reset(new Eval(*lazy));
> }
This seems like a magical incantation to to check the type. Perhaps it's
common in C++, but I find it a bit more subtle than code perhaps should be.
> const Eval * eval = static_cast<const Eval *>(answer.get());
> assert(eval);
I don't like assert. But then I think checked exceptions are a good thing.
Why did you use it here?
> return (*eval)();
> }
> private:
> mutable boost::shared_ptr<Answer> answer;
> };

[snip] And yes, the use of dynamic_cast is a little bothersome, but it's really
just an if statement.
As far as casts go, dynamic_cast seems the least harmful. The only problem I
have with the way it's used it the subtlety of the test. It looks like a
convoluted instanceof test. I hit this example of instanceof on a google:
http://www.artefaktur.com/acdk/docs/...anceof-de.html
I think it's OK in this context because class Thing
knows about the existence of class Lazy and Eval, and these are probably
all in one cpp file.


I'm inclined to believe there is a more concise and direct way of
accomplishing the same goal. But I really don't know what that would be.

This is just something to consider:
http://www.rube-goldberg.com/html/gallery.htm

Please don't take it too seriously, especially since I have not provided a
better solution.
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #6
On Mon, 12 Apr 2004 05:48:00 GMT, "Siemel Naran"
<Si*********@REMOVE.att.net> wrote:
What is a good idiom for handling a lazy object? I see 2 good
possibilities. Any more, any comments? Which way do people here use?
(1)

class Thing {
public:
Thing(double x, double y) : x(x), y(y), calculated(false) { }
double operator()() const {
if (!calculated) calculate();
return z;
}
private:
double x;
double y;
mutable bool calculated;
mutable double z;
void calculate() { z = x+y; }
};
(2)

class Answer {
virtual ~Answer();
};

class Lazy : public Answer {
public:
Lazy(double x, double y) : x(x), y(y) { }
private:
friend class Eval;
double x;
double y;
};

class Eval : public Answer {
public:
Eval(const Lazy& lazy) : z(calculate(lazy))
double operator()() const { return z; }
private:
double z;
static void calculate(const Lazy& lazy) { return lazy.x+lazy.y; }
};

class Thing {
public:
Thing(double x, double y) : answer(new Lazy(x, y)) { }
double operator()() const {
const Lazy * lazy = dynamic_cast<const Lazy *>(answer.get());
if (lazy) {
answer.reset(new Eval(*lazy));
}
const Eval * eval = static_cast<const Eval *>(answer.get());
assert(eval);
return (*eval)();
}
private:
mutable boost::shared_ptr<Answer> answer;
};


How about something like this:

template <class T /*, threading policy? */>
class LazyValue
{
public:
typedef boost::function<T()> creator_t;
LazyValue(creator_t creator)
:m_creator(creator){}

T& get()
{
if (m_creator)
{
m_value = m_creator();
//reset creator
m_creator = creator_t();
}
return m_value;
}

private:
T m_value;
boost::function<T()> m_creator;
};

class Thing {
public:
Thing(double x, double y) : x(x), y(y),
z(bind(&Thing::calculate, this)) { }
double operator()() const {
return z.get();
}
private:
double x;
double y;
mutable LazyValue<double> z;
double calculate() const { return x+y; }
};

This idea can be extended to produce policy controlled, lazy, memory
usage limiting caches (I've done so in Java - a C++ implementation
would be much better. The policies were thread safety, minimum cache
size, how long unused references are held onto, etc. We used it for
loading large configuration objects, XML files, schemas, etc.).

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #7
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:p2Hec.123685
class Answer {
virtual ~Answer();
};

class Lazy : public Answer {
public:
Lazy(double x, double y) : x(x), y(y) { }
private:
friend class Eval;
double x;
double y;
};

class Eval : public Answer {
public:
Eval(const Lazy& lazy) : z(calculate(lazy))
double operator()() const { return z; }
private:
double z;
static void calculate(const Lazy& lazy) { return lazy.x+lazy.y; }
};

class Thing {
public:
Thing(double x, double y) : answer(new Lazy(x, y)) { }
double operator()() const {
const Lazy * lazy = dynamic_cast<const Lazy *>(answer.get());
if (lazy) {
answer.reset(new Eval(*lazy));
}
const Eval * eval = static_cast<const Eval *>(answer.get());
assert(eval);
return (*eval)();
}
private:
mutable boost::shared_ptr<Answer> answer;
};


I am not sure why you need to make such a long way around it. Besides,
I was always told that if you need to use dynamic_cast, you should re-
approach your design, it may have too many interdependencies.


Thinking about your comment on dynamic_cast, I can get rid off it and also
the derivation from Answer (though we now store both objects in memory, not
that that's a bad thing).

class Thing {
public:
Thing(double x, double y) : lazy(new Lazy(x, y)) { }
double operator()() const {
if (!eval) eval.reset(new Eval(*lazy));
return (*eval)();
}
private:
boost::shared_ptr<Lazy> lazy;
mutable boost::shared_ptr<Eval> eval;
};
Jul 22 '05 #8
"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:3O********************@speakeasy.net...
Siemel Naran wrote:
Eval(const Lazy& lazy) : z(calculate(lazy))


I believe you meant to put a semicolon at the end of the above line. No?


Actualy { }

> double operator()() const { return z; } This returns Eval::z no matter what. No magic involved, right?


Right.
> private:
> double z;
> static void calculate(const Lazy& lazy) { return lazy.x+lazy.y; }
This doesn't make sense to me. You seem to be returning a value in a
function whose return type is void.


Sorry, the return type should be double.
I believe you /can/ access lazy.x and lazy.y because of the friendship
relationship;

> class Thing {
> public:
> Thing(double x, double y) : answer(new Lazy(x, y)) { }
> double operator()() const {
> const Lazy * lazy = dynamic_cast<const Lazy *>(answer.get());
> if (lazy) {
> answer.reset(new Eval(*lazy));
> }
This seems like a magical incantation to to check the type. Perhaps it's
common in C++, but I find it a bit more subtle than code perhaps should

be.

Yes, the use of dynamic_cast (or typeid) doesn't seem nice. On the other
hand, the classes Lazy and Eval are so tightly coupled (with one a friend to
the other), and they're probably declared in the same cpp file, so it's not
so bad. But I was thinking about Victor's point, and came up with a
solution that does not use dynamic_cast. Let me know if you think if that
is clearer.
> const Eval * eval = static_cast<const Eval *>(answer.get());
> assert(eval);

I don't like assert. But then I think checked exceptions are a good thing. Why did you use it here?
To assert that if lazy is false then eval must be true. In the other words,
when the lazy object is destroyed the eval object ought to be created. It
checks the logic of the previous if clause. But my other solution does not
have assert.

This is just something to consider:
http://www.rube-goldberg.com/html/gallery.htm


Huh?

Jul 22 '05 #9
"tom_usenet" <to********@hotmail.com> wrote in message
news:l7********************************@4ax.com...
How about something like this:

template <class T /*, threading policy? */>
class LazyValue
{
public:
typedef boost::function<T()> creator_t;
LazyValue(creator_t creator)
:m_creator(creator){}

T& get()
{
if (m_creator)
{
m_value = m_creator();
//reset creator
m_creator = creator_t();
}
return m_value;
}

private:
T m_value;
boost::function<T()> m_creator;
};
Just a side question. Is boost::function<T()> the same as
boost::function<T>? Anyway, this seems similar to my method #2 with the
modification Victor suggested -- not using dynamic_cast, instead store two
objects representing the raw data (class Lazy in my example, m_creator in
yours) and evaluated data (class Eval in my example, m_value in yours).
class Thing {
public:
Thing(double x, double y) : x(x), y(y),
z(bind(&Thing::calculate, this)) { }
double operator()() const {
return z.get();
}
private:
double x;
double y;
mutable LazyValue<double> z;
double calculate() const { return x+y; }
};
Does this boost::function thing handle functions take one, two, or three
arguments?
This idea can be extended to produce policy controlled, lazy, memory
usage limiting caches (I've done so in Java - a C++ implementation
would be much better. The policies were thread safety, minimum cache
size, how long unused references are held onto, etc. We used it for
loading large configuration objects, XML files, schemas, etc.).


Interesting. I didn't think about thread safety. When would it be an
issue? Is it when you create a LazyValue object and pass it to 2 different
threads?

And can you elaborate on this idea of minimum cache size?
Jul 22 '05 #10
"Siemel Naran" <Si*********@REMOVE.att.net> wrote in message news:<k4*******************@bgtnsc05-news.ops.worldnet.att.net>...
What is a good idiom for handling a lazy object?
I think that accessor functions are necessary and sufficient.
I see 2 good possibilities. <snipped code> Any more, any comments? Which way do people here use?


A cursory glance at your code leaves me thinking that you really mean
to ask if there are any C++ idioms for memoizing. This is a more
interesting question, IMHO, and I would be inclined to answer no.
Seldom does a quality C++ library use the same interface for costly
operations as for trivial ones; a more typical C++ idiom would be to
have a costly operation that may return quickly under trivial
conditions. Further, since the underlying semantics for caching block
I/O may be wildly different from those for caching numeric
computations, unifying the interfaces for the two may not be
constructive. Having said all of that, I'm told that the proxy
pattern is useful in developing caching systems.

-cheers,
prs
Jul 22 '05 #11
"anon luker" <ha*********@yahoo.com> wrote in message
A cursory glance at your code leaves me thinking that you really mean
to ask if there are any C++ idioms for memoizing. This is a more
interesting question, IMHO, and I would be inclined to answer no.
What is "memoize"? Could not find it in the Merriam-Webster dictionary.
Seldom does a quality C++ library use the same interface for costly
operations as for trivial ones; a more typical C++ idiom would be to
have a costly operation that may return quickly under trivial
conditions.
Can you give an example?
Further, since the underlying semantics for caching block
I/O may be wildly different from those for caching numeric
computations, unifying the interfaces for the two may not be
constructive. Having said all of that, I'm told that the proxy
pattern is useful in developing caching systems.


What do you mean by sentence #1?
Jul 22 '05 #12
"Siemel Naran" <Si*********@REMOVE.att.net> wrote in message news:<US********************@bgtnsc04-news.ops.worldnet.att.net>...
"anon luker" <ha*********@yahoo.com> wrote in message
A cursory glance at your code leaves me thinking that you really mean
to ask if there are any C++ idioms for memoizing. This is a more
interesting question, IMHO, and I would be inclined to answer no.


What is "memoize"? Could not find it in the Merriam-Webster dictionary.


Google "memoize" - Results 1 - 30 of about 13,000 for memoize. (0.38
seconds)
Seldom does a quality C++ library use the same interface for costly
operations as for trivial ones; a more typical C++ idiom would be to
have a costly operation that may return quickly under trivial
conditions.


Can you give an example?


I/O operations on highly associative large memory stores are a good
example, I think. Do you want to silently cache huge amounts of data?
How do you handle object copy semantics?
Further, since the underlying semantics for caching block
I/O may be wildly different from those for caching numeric
computations, unifying the interfaces for the two may not be
constructive.


What do you mean by sentence #1?


I inferred from your question and your code that you are seeking a
unified caching strategy. My intent was to discourage you by giving
an example of two operations that typically are best cached in
different ways.
Jul 22 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

220
by: Brandon J. Van Every | last post by:
What's better about Ruby than Python? I'm sure there's something. What is it? This is not a troll. I'm language shopping and I want people's answers. I don't know beans about Ruby or have...
28
by: David MacQuigg | last post by:
I'm concerned that with all the focus on obj$func binding, &closures, and other not-so-pretty details of Prothon, that we are missing what is really good - the simplification of classes. There are...
137
by: Philippe C. Martin | last post by:
I apologize in advance for launching this post but I might get enlightment somehow (PS: I am _very_ agnostic ;-). - 1) I do not consider my intelligence/education above average - 2) I am very...
34
by: Steven T. Hatton | last post by:
Pete Vilder mentioned this a few days back. This is the "Compiler-Firewall Idiom", or pimple. It's similar to an approach taken in some Java designs. AAMOF, when I saw it in Java, my first...
4
by: Siemel Naran | last post by:
What is a good idiom for handling a lazy object? I see 2 good possibilities. Any more, any comments? Which way do people here use? (1) class Thing { public: Thing(double x, double y) :...
13
by: Jason Huang | last post by:
Hi, Would someone explain the following coding more detail for me? What's the ( ) for? CurrentText = (TextBox)e.Item.Cells.Controls; Thanks. Jason
41
by: Jordan | last post by:
While writing some code, I realized I had never developed a consistent pattern for checking errors from a method. I have two styles I jump back and forth between, but I'm wondering which is...
15
by: Jiří Paleček | last post by:
Hello, I know the rules for const handling in C++, but I'd like to ask what is the "right" way to use them, eg. when is it appropriate to make a member function const? This came across this...
38
by: Zytan | last post by:
What is the difference between these two lines? Dim args As Object() = New Object() {strText} Dim args As Object() = {strText} args seems usuable from either, say, like so: ...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.