Friday, August 5, 2016

Digest for comp.lang.c++@googlegroups.com - 15 updates in 3 topics

Juha Nieminen <nospam@thanks.invalid>: Aug 05 02:56PM

> map<int, int>::iterator eyIter;
 
Even without reading the rest of the code, this line raises immediately
an alarm, especially since your class has no user-defined copy
constructor nor assignment operator.
 
If you store such an iterator as a member variable for longer than
the duration of a member function call, you are asking for trouble.
(And, if you only need the iterator for the duration of one member
function call, then there's seldom a need to store it as a member
variable. You can simply keep it locally, and if necessary pass it
around to other functions as a function parameter, which not only
makes it safer, but is also better design.)
 
If you really, really need to keep an iterator as a member variable,
you really have to implement a copy constructor and assignment
operator to take care of it when objects of this class are copied
around.
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
"Öö Tiib" <ootiib@hot.ee>: Aug 05 10:04AM -0700

On Friday, 5 August 2016 17:57:04 UTC+3, Juha Nieminen wrote:
 
> Even without reading the rest of the code, this line raises immediately
> an alarm, especially since your class has no user-defined copy
> constructor nor assignment operator.
 
Yes 'eyMap' gets copied but iterator remains to map from what it was
copied in compiler-generated copy.
May be he needed it for debugging usage of that 'eyMap' member (with what
he indicated having issues)?
 
> variable. You can simply keep it locally, and if necessary pass it
> around to other functions as a function parameter, which not only
> makes it safer, but is also better design.)
 
It is not so bad as you put it with iterators (and pointers and
references) to elements of 'map' (or to 'set' or to 'list') since the
situations where those become invalidated are quite limited.
The map to what the iterator is is also owned by object of 'DBE_Info'
so I do not see harm of keeping some "bookmark" iterator to it.

> you really have to implement a copy constructor and assignment
> operator to take care of it when objects of this class are copied
> around.
 
And also he should not to leave it uninitialized in constructor since
iterators do not have useful default values.
Daniel <danielaparker@gmail.com>: Aug 05 06:25AM -0700

Consider
 
class U
{
};
 
class V
{
};
 
class X
{
public:
typedef U u_t;
};
 
class Y
{
public:
typedef U u_t;
typedef V v_t;
};
 
How to distinguish trait class specializations for classes X and Y
(when using the default isn't an option)?
 
// primary template
template<class T, class Enable = void>
struct A {
A()
{
std::cout << "default" << std::endl;
}
};
 
// Matches Y
template <class T>
class A<T,typename std::enable_if<std::is_same<typename T::u_t,U>::value &&
std::is_same<typename T::v_t,V>::value>::type> {
public:
A()
{
std::cout << "has u_t and v_t" << std::endl;
}
};

// How to fix this to match just X?
template <class T>
class A<T,typename std::enable_if<std::is_same<typename T::u_t,U>::value>::type> {
public:
A()
{
std::cout << "has u_t but not v_t" << std::endl;
}
};
 
Thanks,
Daniel
Daniel <danielaparker@gmail.com>: Aug 05 08:37AM -0700

On Friday, August 5, 2016 at 9:25:24 AM UTC-4, Daniel wrote:
 
This is my attempt (comments welcome):
 
class U
{
};
 
class V
{
};
 
template<class T, class Enable = void>
struct S
{
typedef void v_t;
};
 
template <class T>
struct S<T,typename std::enable_if<std::is_same<typename T::v_t,V>::value>::type>
{
};
 
class X
{
typedef U u_t;
};
 
class Y
{
typedef U u_t;
typedef V v_t;
};
 
// primary template
template<class T, class Enable = void>
struct A
{
A()
{
std::cout << "default" << std::endl;
}
};
 
template <class T>
struct A<T,typename std::enable_if<std::is_same<typename T::u_t,U>::value &&
std::is_same<typename T::v_t,V>::value>::type>
{
A()
{
std::cout << "has u_t and v_t" << std::endl;
}
};
 
template <class T>
struct A<T,typename std::enable_if<std::is_same<typename T::u_t,U>::value &&
std::is_void<typename S<T>::v_t>::value>::type>
{
A()
{
std::cout << "has u_t but not v_t" << std::endl;
}
};
 
int main()
{
A<X> a; // has u_t but not v_t
A<Y> b; // has u_t and v_t
A<int> c; // default
}
"Öö Tiib" <ootiib@hot.ee>: Aug 05 08:55AM -0700

On Friday, 5 August 2016 16:25:24 UTC+3, Daniel wrote:
> };
 
> How to distinguish trait class specializations for classes X and Y
> (when using the default isn't an option)?
 
When instantiating a default (not specialization) is error then declare it
but don't define or put 'static_assert' in it.
 
> std::cout << "has u_t but not v_t" << std::endl;
> }
> };
 
That is simple:
 
template <class T>
class A<T,typename std::enable_if<std::is_same<T,X>::value>::type> {
 
Fixed? That implements what comment tells (enables to match just X).
 
If that actually was not it then I am no psychic so I don't know what conditions you actually had in mind. On any case you can use all inbuilt
operators (like ! or ||) in that 'enable_if' to express exact set of
conditions that you want to enable since all of those are 'constexpr'.
 
One library in what lot of things you seem to be interested in are
implemented in generic manner is Boost Type Traits Introspection (or may
be called "Boost.TTI", I'm not sure). So it, its code or its documentation
can save you some time or at least give valuable insights.
Daniel <danielaparker@gmail.com>: Aug 05 09:24AM -0700

On Friday, August 5, 2016 at 11:56:10 AM UTC-4, Öö Tiib wrote:
 
> When instantiating a default (not specialization) is error then declare it
> but don't define or put 'static_assert' in it.
 
In this particular case I don't want it to be an error, though.
 
> template <class T>
> class A<T,typename std::enable_if<std::is_same<T,X>::value>::type> {
 
> Fixed? That implements what comment tells (enables to match just X).
 
It's a less general solution to what I proposed, though, as it only works
for class X, and not other classes that have typedefs
 
typedef U u_t;
typedef V v_t;
 
> implemented in generic manner is Boost Type Traits Introspection (or may
> be called "Boost.TTI", I'm not sure). So it, its code or its documentation
> can save you some time or at least give valuable insights.
 
That's a good suggestion, thanks.
 
Best regards,
Daniel
Real Troll <real.troll@trolls.com>: Aug 05 12:00AM -0300

On 04/08/2016 21:16, Mr Flibble wrote:
> {
> return num * num; /* Does not check for overflow */
> }
So is there any need to use int in modern programming?
 
Tried your suggestion and used <stdint.h> but as the program is very
small, there is no way to measure the speed but I take your word for it.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Aug 04 08:06PM -0700

On Thursday, August 4, 2016 at 10:05:02 PM UTC-4, Real Troll wrote:
> So is there any need to use int in modern programming?
 
Int is typically optimized to be the fastest type for the machine's
native word size. In most cases this equates naturally to a 32-bit
value, or 64-bit value even if the standard says it can be less. As
such, the substitute explicit-sized types could be used, but if you
are writing portable code designed for speed, and you know the machine
size targets will be at least 32-bits, for example, then using int
will be the fastest on the target hardware, while guaranteeing at
least 32-bits of data storage for the type (as per your knowledge of
the machine targets for the app).
 
Best regards,
Rick C. Hodgin
David Brown <david.brown@hesbynett.no>: Aug 05 12:28PM +0200

On 04/08/16 20:40, Rick C. Hodgin wrote:
 
> We can't see God. Even with the evidence pointing to Him, of which there
> is a multitude, we still don't see Him. Not yet. That's where faith
> comes in.
 
If there were evidence for god, there would be no need of faith -
regardless of whether or not you can see him.
 
You can't see air, or bacteria, or radio waves - but we know they exist
because of the overwhelming evidence. There is no need for "faith"
about such things.
 
If there were the type of evidence for a god, as you claim there is,
then there would be no need of faith - we would know there is a god in
the same way that we know there is air, bacteria and radio waves. But
that would undermine the whole principle of faith, and "blessed are
those who have not seen and yet believe".
 
Ergo, if there is any evidence for a god of some sort, it is limited and
unconvincing.
 
As the sausage eater says, you can't have it both ways.
 
> truth, what's coming in the future, etc. We read about it. It's confirmed
> here in the world through observation, and even more so now that we are
> beginning to understand genetics.
 
You start with two assumptions:
 
1. Everything written in the Bible is literally true.
(We will put aside for the moment questions such as which Bible, which
sources, which translation, and more importantly, whose human
interpretations.)
 
2. Everything that contradicts assumption 1 is the product of Satan
and/or sin.
 
 
/All/ your claims of evidence build on those two assumptions. This is
circular reasoning. You take it on faith that these two assumptions
hold. That's fair enough - that's the sort of "leap of faith" that
defines religious beliefs. But you can't expect anyone who does not
hold the same assumptions to accept your claims of evidence - because
those claims rest on the assumptions.
 
When someone discovers a fascinating new piece of information - a
fossil, a mathematical pattern, some new biological system, etc., you
have new "evidence" about how the world works. With your way of
thinking, step one is to see if this new evidence contradicts assumption
1 above. If you can claim (no matter how contorted the reasoning) that
there is no contradiction with the Bible, you then proclaim that you
have "evidence that the Bible is true". If not, then you automatically
have "evidence that Satan is misleading us".
 
But clearly, that is not evidence in any other sense. To look at it
objectively, scientists will ask how it fits with existing theories and
other evidence. If it contradicts existing theories, and the new
evidence is strong enough (it must be repeatable and observed by more
than one independent group), then the search starts for new theories and
explanations. Scientists look for answers to fit the questions, not for
ways to make the questions fit the existing answers.
David Brown <david.brown@hesbynett.no>: Aug 05 12:32PM +0200

On 04/08/16 20:52, Daniel wrote:
> seem so very far off.
 
>> Real evidence man lived with dinosaurs ...
 
> Uh, oh :-) I think you're making fun of us now.
 
Poe's law: "Without a clear indicator of the author's intent, parodies
of extreme views will be mistaken by some readers or viewers as sincere
expressions of the parodied views."
 
Basically, it is impossible for us to tell for sure if he is sincere or
parodying religious fanatics here.
 
Unfortunately, however, I think he /is/ sincere.
David Brown <david.brown@hesbynett.no>: Aug 05 12:42PM +0200

On 05/08/16 05:06, Rick C. Hodgin wrote:
> will be the fastest on the target hardware, while guaranteeing at
> least 32-bits of data storage for the type (as per your knowledge of
> the machine targets for the app).
 
No, the type which will be the fastest on your target while guaranteeing
at least 32 bits is "int_fast32_t". That is /precisely/ what that type
says. On a great many modern systems, "int_fast32_t" is a typedef of
"int", but it may not be.
 
For many types of programming, you can of course assume "int" is at
least 32 bits - anything on *nix, Posix, Windows (hopefully we've
repressed all memories of 16-bit Windows by now), etc.
 
So for many purposes, "int" is perfectly good (and just as fast as
"int_fast32_t", and just as safe/unsafe, since it is often the same
type). But if you want to be careful and about what you are saying,
and/or write highly portable code, then "int" is roughly the same as
"int_fast16_t", not "int_fast32_t". "Long int" is needed to guarantee
32 bits, and that certainly does not have to be the fastest such type.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Aug 05 04:57AM -0700

On Friday, August 5, 2016 at 6:42:52 AM UTC-4, David Brown wrote:
> at least 32 bits is "int_fast32_t". That is /precisely/ what that type
> says. On a great many modern systems, "int_fast32_t" is a typedef of
> "int", but it may not be.
 
It's easily explained ... I did not know int_fast32_t existed.
 
Are there any cases where int and int_fast32_t do not resolve to the
same size type on a compiler designed for 32-bit hardware?
 
Best regards,
Rick C. Hodgin
David Brown <david.brown@hesbynett.no>: Aug 05 02:21PM +0200

On 05/08/16 13:57, Rick C. Hodgin wrote:
 
> It's easily explained ... I did not know int_fast32_t existed.
 
> Are there any cases where int and int_fast32_t do not resolve to the
> same size type on a compiler designed for 32-bit hardware?
 
I believe there are a few systems where "int" is 64-bit, in which case
int_fast32_t may be "short". And I know of a 32-bit processor where 16
bit data could be noticeably faster (a 32-bit 68k device with no caches
and an external 16-bit data bus - reading or writing 32-bit values took
several cycles more than accessing 16-bit values). The compiler I used
there had 32-bit "int", but could conceivably have used 16-bit int.
 
But I think on just about any reasonable and fairly modern 32-bit
device, int_fast32_t and int will resolve to the same 32-bit hardware type.
 
However, they may not resolve to the same /logical/ type. On most
32-bit devices, "long" will also resolve to the same 32-bit hardware
type (and also on 64-bit Windows longs are 32-bit, because the Win64 ABI
is a bit silly). There is no reason to suppose that "int_fast32_t" (and
int_least32_t and int32_t) will resolve to "int" rather than "long".
Indeed, on 32-bit ARM gcc these resolve to "long".
 
For the most part, it doesn't make a big difference - but if you try to
mix pointers to int with pointers to long (or int32_t, or whatever),
then even though the hardware implementation is the same, they are
logically incompatible types in C. You would be able to assign an
int32_t* to a long*, but not to an int*, and a compiler could assume
that an int* and an int32_t* cannot alias. This is, of course, no
different than the normal rules about int* and long* compatibilities -
but it could be worth noting.
Daniel <danielaparker@gmail.com>: Aug 05 05:29AM -0700

On Tuesday, August 2, 2016 at 7:44:37 PM UTC-4, Rick C. Hodgin wrote:
 
> [My wife is] still a non-believer to this day,
> and I have no affection, no companionship, no close confidant in my wife,
> yet we remain married because of my son (born in 2004).
 
Rick,
 
Nobody on this newsgroup wishes you harm. But none of us are qualified to tell
you what you have to do. That you have to learn for yourself. It sounds like
you realize that something is wrong with your life, it's a start.
 
When you say that you have no companionship from your wife, have you thought
about it from your wife's point of view? That the man she thought she had
married, that he isn't there anymore? Have you thought about her being
deprived of attention and affection? Do you practice the Mosaic law,
"whatever is hurtful to you, do not do to any other person", when it comes to
your family? These are just questions, they do not require answers,
particularly not here.
 
My suggestion would be to focus more on fixing things with your wife, your family, and focus less on your own needs. Focus on what you have to give,
not on what you think you need.
 
And with that, I'll drop off this conversation :-)
 
Best regards,
Daniel
scott@slp53.sl.home (Scott Lurndal): Aug 05 12:38PM

>> return num * num; /* Does not check for overflow */
>> }
>So is there any need to use int in modern programming?
 
Sure - there are a number of POSIX interfaces that have either
int parameters or int return values.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: