Tuesday, December 6, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 12 topics

Ralf Goertz <me@myprovider.invalid>: Dec 06 02:03PM +0100

Hi,
 
is it possible to have a lambda expression as a template argument? If
not why not? I get an error when I try to compile the following
 
typedef std::set< std::set<int>,
[](const std::set<int>&x,const std::set<int>&y){
return x.size()==y.size() ? x<y : x.size()<y.size();
}> Setset;
 
error: lambda-expression in template-argument
 
Background is that I'd rather have sets with fewer elements sorted
before sets with more elements.
"Öö Tiib" <ootiib@hot.ee>: Dec 06 06:26AM -0800

On Tuesday, 6 December 2016 15:02:28 UTC+2, Ralf Goertz wrote:
> Hi,
 
> is it possible to have a lambda expression as a template argument?
 
Probably it is not meant to be possible to have since type of lambda
expression is said to be unspecified and compilers seem to hate
lambda expressions in unevaluated contexts like as arguments of
decltype or sizeof.
 
> return x.size()==y.size() ? x<y : x.size()<y.size();
> }> Setset;
 
> error: lambda-expression in template-argument
 
That is different issue. Lambda expression is not type, it is
value of unspecified type. Learn to use std::set with
comparator:
 
auto comp = [](int x, int y){ return x < y; };
auto set = std::set<int,decltype(comp)>( comp );>
 
> Background is that I'd rather have sets with fewer elements sorted
> before sets with more elements.
 
That background was kinda whoosh for me.
Ralf Goertz <me@myprovider.invalid>: Dec 06 03:42PM +0100

Am Tue, 6 Dec 2016 06:26:59 -0800 (PST)
> unspecified type. Learn to use std::set with comparator:
 
> auto comp = [](int x, int y){ return x < y; };
> auto set = std::set<int,decltype(comp)>( comp );>
 
Thanks, The problem with this solution is that I can't use it as
typedef. I don't want to give „comp" as argument whenever I declare a
variable of that type. But of course I can do it with comp being a class
defining a „bool operator()(…)"
 
> > Background is that I'd rather have sets with fewer elements sorted
> > before sets with more elements.
 
> That background was kinda whoosh for me.
 
I need sets of sets of int. With defaults I get
 
{{1,2,5},{3},{3,4}}
 
But I need them in the order:
 
{{3},{3,4},{1,2,5}}
 
Smaller sets before bigger sets.
Ralf Goertz <me@myprovider.invalid>: Dec 06 04:38PM +0100

Am 6 Dec 2016 15:27:23 GMT
> { return x.size() == y.size() ? x < y : x.size() < y.size(); }};
 
> using setset = ::std::set < ::std::set< int >, fun >;
 
> work?
 
Indeed, and that's what I am doing now, see my answer to Öö. But whether
this is straightforward (compared to my initial idea which seemed much
more straightforward to me) lies in the eye of the beholder. ;-)
bleachbot <bleachbot@httrack.com>: Dec 06 01:22AM +0100

ram@zedat.fu-berlin.de (Stefan Ram): Dec 06 10:29AM

>How does one pronounce »GotW« (in the sense of »Guru of the Week«)?
 
Someone wrote about it something like »I pronounce it so that it
rhymes with "gotcha".«. Some years ago I read this, but I read not
carefully, and so I understood »I pronounce it "gotcha".«, and so
I pronounced it »gotcha«, but recently I started to wonder whether
this pronunciation was correct. I now wonder what that pronunciation
that rhymes with »gotcha« might be, »gotwa«? It does not seem to
be »got double-u«, although this contains »u«, which in slang has
the same meaning as »cha« (»you«).
ram@zedat.fu-berlin.de (Stefan Ram): Dec 06 01:06PM

>is it possible to have a lambda expression as a template argument?
 
A non-type template-parameter shall have one of the
following (optionally cv-qualified) types: integral or
enumeration type, pointer to object or pointer to function,
lvalue reference to object or lvalue reference to function,
pointer to member, std::nullptr_t, or a type that contains a
placeholder type.
ram@zedat.fu-berlin.de (Stefan Ram): Dec 06 03:27PM

> [](const std::set<int>&x,const std::set<int>&y){
> return x.size()==y.size() ? x<y : x.size()<y.size();
> }> Setset;
 
Wouldn't the straightforward
 
struct fun
{ bool operator()
( const ::std::set< int >& x, const ::std::set< int >& y) const
{ return x.size() == y.size() ? x < y : x.size() < y.size(); }};
 
using setset = ::std::set < ::std::set< int >, fun >;
 
work?
ruben safir <ruben@mrbrklyn.com>: Dec 06 09:05AM -0500

Hello
 
I'm having trouble with this imput of data from a PNG image. The specification says that "chunks" have a 4 byte field that is the length of the attached data segment. I tried to read the length in for a chunk that has a length of 13, which was confirmed in a hexdump
 
0000000 211 120 116 107 015 012 032 012 -->>000 000 000 015<<-- 111 110 104 122
0000010 000 000 041 215 000 000 007 165 010 006 000 000 001 206 055 074
0000020 336 000 000 000 004 147 101 115 101 000 000 261 217 013 374 141
 
I am storing the data in a uint32_t variable using the following code, but the value keeps showing up with a huge number 218103808 which happens to be the number that is evaluated by iostream for the value of the whole chunk
 
 
done reading header
 
 
 
Sizeof Chunk 4
Raw Chunk Number 0: 218103808
***LENGTH****
Length value => 218103808
Sizeof Byte 1
Character 0::
^@
Byte 0::
0
Character 1::
^@
Byte 1::
0
Character 2::
^@
Byte 2::
0
Character 3::

Byte 3::
13
 
 
As yet, when I break it down by single bytes, it returns 0 0 0 13, which is correct.
ddd seems to say the same thing, and I don't know why. When evaluated as 4 bytes,
you get this large number, but when you evaluate them seperately, each byte, it
comes out right.
 
The code snippet I'm using looks like this
 
in the .h file
#ifndef PNGPRJ
#define PNGPRJ
#include <inttypes.h>
namespace png_proj{
typedef uint32_t CHUNK;
 
 
 
In the .cpp file
void Image::read_chunk()
{
char * cur = get_index();
CHUNK * tmp = reinterpret_cast<CHUNK *>(cur);
std::cout << std::endl << "Sizeof Chunk " << sizeof(*tmp) << std::endl;
for(int j = 0; j<4; j++){
std::cout << "Raw Chunk Number " << j << ": " << *tmp << std::endl;


switch ( j ) {
case 0:
std::cout << "***LENGTH****" << std::endl;
set_length(static_cast<int32_t>(*tmp));
std::cout << "Length value => " << static_cast<int>(*tmp) << std::endl;
break;
 
case 1:
std::cout << "***TYPE****" << std::endl;
set_type(static_cast<int32_t>(*tmp));
break;
 
case 2:
{
std::cout << "***DATA****" << std::endl;
unsigned long int l = static_cast<unsigned long int>(get_length());
std::cout << "buffer size should be " << get_length() << std::endl;
int8_t * buffer = new int8_t[l];
std::cout << "buffer element size is " << *buffer << std::endl;
std::cout << "buffer size is " << l << std::endl;
for(unsigned int k = 0; k < get_length(); k++){
buffer[k] = static_cast<int8_t>(tmp[k]);
std::cout << "data " << *buffer << std::endl;
}
set_data(buffer);
}
break;
 
case 3:
std::cout << "***CRC****" << std::endl;
set_crc(static_cast<int32_t>(*tmp));
break;
 
default:
std::cout << "***NOMANDSLAND****" << std::endl;
break;
} /* ----- end switch ----- */
 
char * tmp2 = reinterpret_cast<char *>(tmp); //reading each byte
std::cout << "Sizeof Byte " << sizeof(*tmp2) << std::endl;
//std::cout << "Mark ==>>" << __LINE__ << std::endl;
for(int i=0; i<4; i++){
std::cout << "Character " << i << "::" << std::endl << "\t" << *tmp2 << std::endl;
std::cout << "Byte " << i << "::" << std::endl << "\t" << static_cast<unsigned long int>(*tmp2) << std::endl;
tmp2++;
}
std::cout<<std::endl;
std::cout<<std::endl;
tmp++;
cur = ( reinterpret_cast<char*>(tmp) );
}
set_index(cur);
}
 
 
 
I dug through libpng since this seems to not being doing what I expected. They seem to set it up as 4 byte array
 
void /* PRIVATE */
png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
{
png_uint_32 chunk_name;
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
int keep; /* unknown handling method */

No comments: