Sunday, September 6, 2015

Digest for comp.lang.c++@googlegroups.com - 17 updates in 4 topics

woodbrian77@gmail.com: Sep 06 11:04AM -0700

> there's something to be said for the original form.
> I was influenced toward more compact forms by the
> author of the Boost Multi_index library.
 
I've been doing more of this lately and ran into
a problem when I tried removing the space between
the '*' and the '=' in the following
 
bool Flush (::sockaddr* =nullptr,::socklen_t=0);
 
The compiler "thought" the *= was a multiply
and assign and that didn't make sense in the context.
I recall having a similar problem when using a ?:
statement and had 3 ':' in a row. I had to leave a
space between the first and second ':' to help the
compiler out.
 
Brian
Ebenezer Enterprises - "The wicked spies upon the
righteous and seeks to kill him." Psalms 37:32
 
http://breitbart.com
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 06 11:38PM +0100

On Sun, 6 Sep 2015 11:04:56 -0700 (PDT)
> statement and had 3 ':' in a row. I had to leave a
> space between the first and second ':' to help the
> compiler out.
 
No, not to help the compiler out, but to write valid C++ code. C++
tokens are greedy (aka the "max munch" rule).
 
Quite why you should want to obfuscate your code I don't know, but if
you are going to do so then you need to learn the rules, and not try
blaming the compiler.
"Chris M. Thomasson" <nospam@nospam.nospam>: Sep 05 05:53PM -0700

> "Mr Flibble" wrote in message
> news:EYOdneWs29O7pXbInZ2dnUU7-L-dnZ2d@giganews.com...
 
[...]
 
> There is absolutely no evidence whatsoever that King David or Jesus Christ
> existed, none.
 
http://www.whitepages.com/name/Jesus-Christ
 
;^)
"Chris M. Thomasson" <nospam@nospam.nospam>: Sep 05 05:54PM -0700

> news:msg2q7$dcf$1@speranza.aioe.org...
 
> > "Mr Flibble" wrote in message
> > news:EYOdneWs29O7pXbInZ2dnUU7-L-dnZ2d@giganews.com...
 
[...]
 
> > There is absolutely no evidence whatsoever that King David or Jesus
> > Christ existed, none.
 
> http://www.whitepages.com/name/Jesus-Christ
 
I wonder how many of them claim to be the son of god?
Daniel <danielaparker@gmail.com>: Sep 06 08:21AM -0700

On Saturday, September 5, 2015 at 2:45:13 PM UTC-4, Mr Flibble wrote:
 
> Theology is not scientific and is arguably not scholarly either.
 
Theology? But historians of ancient israel are not theologians.
 
It's been a while since the Christian movement was powerful enough to have the heretics burned, almost 200 years. Critical Biblical scholarship has been thriving since, modern biblical scholarship combines data from archaeological and non-biblical sources, linguistic comparisons of Biblical Hebrew and ancient transcriptions, sociological models, etc. If you want to make interesting statements about it, you need to do some reading first.
 
Daniel
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Sep 06 06:39PM +0100

On 06/09/2015 16:21, Daniel wrote:
> On Saturday, September 5, 2015 at 2:45:13 PM UTC-4, Mr Flibble wrote:
> It's been a while since the Christian movement was powerful enough to have the heretics burned, almost 200 years. Critical Biblical scholarship has been thriving since, modern biblical scholarship combines data from archaeological and non-biblical sources, linguistic comparisons of Biblical Hebrew and ancient transcriptions, sociological models, etc. If you want to make interesting statements about it, you need to do some reading first.
 
"Critical Biblical scholarship"? A three word oxymoron, impressive mate.
 
/Flibble
Daniel <danielaparker@gmail.com>: Sep 06 12:29PM -0700

On Sunday, September 6, 2015 at 1:39:10 PM UTC-4, Mr Flibble wrote:
 
> "Critical Biblical scholarship"? A three word oxymoron, impressive mate.
 
I find it curious that the two members of this community who feel the most need to pronounce on the subject, one, our "village atheist", and two, the evangelical literalist, both appear to have no interest in the relevant historical scholarship. More time with the books, mate! and less time at the pub.
 
Daniel
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Sep 06 08:50PM +0100

On 06/09/2015 20:29, Daniel wrote:
> On Sunday, September 6, 2015 at 1:39:10 PM UTC-4, Mr Flibble wrote:
 
>> "Critical Biblical scholarship"? A three word oxymoron, impressive mate.
 
> I find it curious that the two members of this community who feel the most need to pronounce on the subject, one, our "village atheist", and two, the evangelical literalist, both appear to have no interest in the relevant historical scholarship. More time with the books, mate! and less time at the pub.
 
The problem you seem to be having is your assumption that the Bible is a
historical document: it isn't.
 
/Flibble
Daniel <danielaparker@gmail.com>: Sep 06 01:21PM -0700

On Sunday, September 6, 2015 at 3:50:39 PM UTC-4, Mr Flibble wrote:
 
> The problem you seem to be having is your assumption that the Bible is a
> historical document: it isn't.
 
"Oh Lord, give us strength ...", well, the problem you seem to be having is your assumption that C++ is a fifth generation AI language (I can make sentences like that too.)
 
Anyway, I wish you a very good day,
Daniel
mark <mark@invalid.invalid>: Sep 06 01:08PM +0200

I'm looking for a sort function that can sort standard library
containers based on member fields.
 
struct A {
int v1;
std::string v2;
};
 
std::vector<A> v;
bool ascending = true;
 
I would like to perform sorting like this:
my_sort(v, ascending, A::v2);
 
There must be some nice C++11 magic that can do that...
SG <s.gesemann@gmail.com>: Sep 06 04:54AM -0700

Am Sonntag, 6. September 2015 13:09:07 UTC+2 schrieb mark:
 
> I would like to perform sorting like this:
> my_sort(v, ascending, A::v2);
 
> There must be some nice C++11 magic that can do that...
 
Anything wrong with just using std::sort and a lambda function?
 
std::sort(v.begin(), v.end(), [](A const& l, A const& r) {
return l.v2 < r.v2;
});
 
Using the Boost.Bind library, this could be:
 
std::sort(v.begin(), v.end(),
bind(&A::v2, _1) < bind(&A::v2, _2)
);
 
But you could also write your own generic functor. Something like this
perhaps:
 
template<class T>
struct member_less_than;
 
template<class C, class T>
struct member_less_than<T C::*> {
T C::*member_pointer;
 
bool operator()(C const& a, C const& b) const {
return (a.*member_pointer) < (b.*member_pointer);
}
};
 
template<class C, class T>
member_less_than<T C::*> make_mlt(T C::*member_ptr) {
member_less_than<T C::*> result = { member_ptr };
return result;
}
 
:::
 
std::sort(v.begin(), v.end(), make_mlk(&A::v2));
 
Another option would be to move the member pointer out of the struct
and turn it into a template parameter (yes, that's actually doable
and might be preferable).
 
All the code you see here is untested and probably buggy but should
work "in principle". In particular, I'm not sure if I got the member
pointer syntax right because I hardly use member pointers.
 
Cheers!
SG
bartekltg <bartekltg@gmail.com>: Sep 06 03:20PM +0200

On 06.09.2015 13:08, mark wrote:
> bool ascending = true;
 
> I would like to perform sorting like this:
> my_sort(v, ascending, A::v2);
 
 
Old C++ magic was enough:
 
The first is a very simple example, but it looks
at values ascending and field_index every time
it compare two "A" object.
The second comparator should have this optimized out
by compilator. Still, there are better ways to do it
(for example, there you have tu maintain a class, enum,
and body od comparator, and keep it consistent. Idea
described by SG, with pointers to members may be much
better for larger classes/structures) but with more
'template magic'.
 
 
#include <iostream>
#include <algorithm>
#include <vector>
 
 
using namespace std;
 
 
 
struct A {
int v1;
std::string v2;
A(int number, std::string string):v1(number),v2(string) {} ;
};
 
std::vector<A> v;
bool ascending = true;
 
enum field
{
V1 = 1,
V2 = 2
};
 
 
struct A_comparator
{
bool ascending;
int field_index;
 
A_comparator (bool Ascending, int Field_index):
ascending(Ascending), field_index(Field_index) {};
bool operator () (const A &x, const A &y)
{
if (ascending)
{
if (field_index==1)
return x.v1<y.v1;
else
return x.v2<y.v2;
}else
{
if (field_index==1)
return x.v1>y.v1;
else
return x.v2>y.v2;
}
}
};
 
template <bool ascending, field field_index>
struct A_comparator2
{
A_comparator2 () {};
bool operator () (const A &x, const A &y)
{
if (ascending)
{
if (field_index==V1)
return x.v1<y.v1;
else
return x.v2<y.v2;
}else
{
if (field_index==V1)
return x.v1>y.v1;
else
return x.v2>y.v2;
}
}
};
 
 
 
int main()
{
std::vector<A> v;
 
v.push_back(A(70,"70"));
v.push_back(A(30,"93"));
v.push_back(A(40,"67"));
 
bool ascending = true;
 
 
sort (v.begin(), v.end(), A_comparator(true,2));
 
sort (v.begin(), v.end(), A_comparator2<true,V1>());
 
 
return 0;
}
 
 
bartekltg
mark <mark@invalid.invalid>: Sep 06 07:12PM +0200

Thanks for the replies. I figured out the template magic.
 
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
 
template<class container_t_, class el_t_, class field_t_>
void my_sort(container_t_& cnt, field_t_ el_t_::* field, bool asc) {
std::sort(cnt.begin(), cnt.end(), [field,asc](el_t_ a, el_t_ b) {
return asc ? a.*field < b.*field : a.*field > b.*field;
});
}
 
struct A {
int v1;
std::string v2;
};
 
void printVec(const std::vector<A>& v) {
for(auto& val : v) std::cout << val.v1 << " ";
std::cout << std::endl;
}
 
int main() {
std::vector<A> v = { {2, "2"}, {3, "3"}, {1, "1"} };
my_sort(v, &A::v2, true);
printVec(v);
my_sort(v, &A::v1, false);
printVec(v);
}
mark <mark@invalid.invalid>: Sep 06 07:53PM +0200

On 2015-09-06 19:12, mark wrote:
> return asc ? a.*field < b.*field : a.*field > b.*field;
> });
> }
 
GCC in C++14 mode can do some nice auto magic (but it's apparently part
of concepts lite and not in the standard):
 
void my_sort(auto& cnt, auto field, bool asc) {
std::sort(cnt.begin(), cnt.end(), [field,asc](auto a, auto b) {
return asc ? a.*field < b.*field : a.*field > b.*field;
});
}
 
This should be valid C++14:
 
auto my_sort = [](auto& cnt, auto field, bool asc) {
std::sort(cnt.begin(), cnt.end(), [field,asc](auto a, auto b) {
return asc ? a.*field < b.*field : a.*field > b.*field;
});
};
SG <s.gesemann@gmail.com>: Sep 06 10:56AM -0700

Am Sonntag, 6. September 2015 19:13:17 UTC+2 schrieb mark:
> return asc ? a.*field < b.*field : a.*field > b.*field;
> });
> }

A couple of suggestions:
 
(1) Since you are now generic over the kind of container to sort, you
should probably use the non-member begin/end functions to be a
little more flexible. This way, the function will work for raw
arrays as well, for example.
 
(2) The signature of your lambda function is suboptimal because you
take its arguments by value which will produce unnecessary copies
which is quite costly for non-trivial types like std::string.
 
(3) You can avoid the "asc?:" branch by moving the check outside of
the sort function. There should not be a big difference if your
CPU does branch prediction.
 
So, after some tweaking I get:
 
template<class Cont, class Clazz, class T, class Func>
void sort_by_member_func(Cont& cnt, T Clazz::* field, Func func) {
using std::begin; // With these we can avoid the std:: later
using std::end; // which then also allows ADL to kick in.
std::sort(begin(cnt), end(cnt),
[field, &func](T const& a, T const& b) {
return func(a.*field, b.*field);
}
);
}
 
template<class Cont, class Clazz, class T>
void sort_by_member(Cont& cnt, T Clazz::* field, bool asc) {
if (asc) {
sort_by_member_func(cnt, field, std::less<T>());
} else {
sort_by_member_func(cnt, field, std::greater<T>());
}
}
 
Cheers!
SG
mark <mark@invalid.invalid>: Sep 06 09:08PM +0200

On 2015-09-06 19:56, SG wrote:
 
Thanks for your comments.
 
> (2) The signature of your lambda function is suboptimal because you
> take its arguments by value which will produce unnecessary copies
> which is quite costly for non-trivial types like std::string.
 
You are right. The 'real' code actually has pointer containers, so it
doesn't matter there.
 
> (3) You can avoid the "asc?:" branch by moving the check outside of
> the sort function. There should not be a big difference if your
> CPU does branch prediction.
 
I had too much compiler faith and was expecting the test to be pulled
out. I did a test and it does make a small difference on both GCC and VC++.
DeMarcus <demarcus_at_hotmail_com@tellus.orb>: Sep 06 08:32PM +0200

> reason nothing resonated with me. Are there any key features that
> made you like D or is it just the overall feel and interaction of
> many smaller properties that makes programming in D fun for you?
 
No, I haven't taken a look into D, I just bought the book. What I think
is good is that Alexandrescu is helping the D community out developing
their language, making him able to see what could also work for C++ that
he knows inside out. For that reason I think Alexandrescu is a great
asset to the C++ community too.
 
Br,
Daniel
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: