Sunday, July 9, 2017

Digest for comp.lang.c++@googlegroups.com - 18 updates in 5 topics

Marcel Mueller <news.5.maazl@spamgourmet.org>: Jul 09 06:24PM +0200

I have found a work around:
 
 
#include <stdio.h>
 
template <typename ...A>
struct MsgTemplate
{ int ID;
const char* Text;
};
 
static constexpr const struct MyClassTemplates
{ const MsgTemplate<const char*> SOMETHING_WENT_WRONG =
{ 1001, "Something went wrong: %s" };
// more templates ...
} MyClassTemplates;
 
struct MyClass
{
static constexpr const struct MyClassTemplates Templates =
MyClassTemplates;
};
 
 
But I have no idea why this additional symbol fixes the problem.
Compiler-Bug?
 
 
Marcel
"Öö Tiib" <ootiib@hot.ee>: Jul 09 04:16PM -0700

On Sunday, 9 July 2017 19:24:40 UTC+3, Marcel Mueller wrote:
> };
 
> But I have no idea why this additional symbol fixes the problem.
> Compiler-Bug?
 
I don't think so. Some C++ compilers permit anonymous structs as an
extension to standard C++ language. So what you wrestle there with
seems most likely to be that extension. You made the struct not
anonymous and that works better.
ram@zedat.fu-berlin.de (Stefan Ram): Jul 09 05:25PM

>How can we change the >> operator to call a user defined function to
>scan the characters?
 
I have an example program that I posted to another newsgroup some
months ago, but it is more complicated than necessary for your needs.
Maybe someone can strip it down? (I don't have time for this now.
There are also some stylistic issues with the code. No time to fix
these either.) Maybe someone can explain it all in more detail?
 
The program shows how to imbue a stream with a list of separators
which are given as arguments to a variadic template.
(You don't ask for this and might not need it. The code also
uses wide characters in some parts, which you might not need.)
 
So,
 
in.imbue
( ::std::locale
( in.getloc(), new ::is_delim< wchar_t, L':', L';', L'|', L'=' >{} ))
 
imbues »in« with a locale that uses »:«, »;«, »|« and »=« as
separators.
 
Now,
 
"1:;|=3.14=|hello world!\tauf Wiedersehen!...::;;-135.56"
 
is split into the following four lines
 
1
3.14
hello world! auf Wiedersehen!...
-135.56
 
. Here's the full code (which in parts might contain code
from other posters of the German newsgroup de.comp.lang.iso-c++):
 
#include <iostream>
#include <ostream>
#include <sstream>
#include <string>
 
template< typename T, T... Args >struct is_delim;
 
template< typename charT, charT value >
struct is_delim< charT, value >: ::std::ctype< charT >
{ ::std::basic_string< charT >delim;
is_delim( ):delim{value}{ ::std::cerr << "accumulated (2): void.\n"; };
is_delim( ::std::basic_string< charT >string ):delim{ value + string }{};
bool do_is( ::std::ctype_base::mask const m, charT const c )
const
{ bool const s = m & ::std::ctype_base::space;
if( s &&( c == 9 || c == 32 ))return false;
if( s &&( delim.find( c )!= ::std::string::npos ))return true;
return ::std::ctype< charT >::do_is( m, c ); }};
 
template< typename charT, charT value, charT ... args >
struct is_delim< charT, value, args... >: ::std::ctype< charT >
{ ::std::basic_string< charT >delim;
is_delim( ):delim{}{};
is_delim( ::std::basic_string< charT >string ):delim{ string }{};
is_delim< charT, args... >rest{ delim + value };
bool do_is( ::std::ctype_base::mask const m, charT const c )
const { return rest.do_is( m, c ); }};
 
template< typename charT >
void show( ::std::basic_string<charT> const arg )
{ for( auto ch : arg )::std::cerr <<( char )ch;
::std::cerr << "\n"; }
 
int main()
{ using namespace ::std::literals;
::std::wistringstream in
{ L"1:;|=3.14=|hello world!\tauf Wiedersehen!...::;;-135.56"s };
in.imbue
( ::std::locale
( in.getloc(), new ::is_delim< wchar_t, L':', L';', L'|', L'=' >{} ));
{ int m; double x, y; ::std::wstring s;
in >> m >> x >> s >> y;
{ ::std::cout << m << '\n';
::std::cout << x << '\n';
show( s );
::std::cout << y << '\n'; }}}
ram@zedat.fu-berlin.de (Stefan Ram): Jul 09 05:35PM

>( ::std::locale
> ( in.getloc(),
> new ::is_delim< wchar_t, L':', L';', L'|', L'=' >{} ))
 
Ah, this is using the constructor
 
template <class Facet> locale(const locale& other, Facet* f);
 
and then
 
22.4.1.1 Class template ctype
 
, which is a facet, implementing its function
 
virtual bool do_is(mask m, charT c) const;
 
. So one should be able do this:
 
::std::cin.imbue
( ::std::locale
( ::std::cin.getloc(), new my_ctype_implementation_with_do_is() ));
 
(untested). No need for templates. Then:
 
struct my_ctype_implementation_with_do_is : ::std::ctype< char >
{ bool do_is( ::std::ctype_base::mask const m, charT const c )
const
{ /* overwrite your character categories here, or otherwise just: */
return ::std::ctype< charT >::do_is( m, c ); }};
 
.
"Öö Tiib" <ootiib@hot.ee>: Jul 08 04:29PM -0700

On Sunday, 9 July 2017 01:19:52 UTC+3, jacobnavia wrote:
> 23 }
> 24 }
> 25 }
 
Annoying habit to put these line numbers there to make it non-copyable.
 
 
> The problem here is that the scanner considers that
> "word" and "word,word" are two different words.
 
> Apparently just searches the first non blank character.
 
You want to specify more delimiters in istream than white space?
 
> How can we change the >> operator to call a user defined function to
> scan the characters?
 
> My C++ knowledge doesn't go that far.
 
To my knowledge you must imbue stream with suitably for your taste
screwed up locale.
 
#include <locale>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <sstream>
 
class Delims
: public std::ctype<char>
{
mask t_[table_size];
public:
explicit Delims(size_t refs = 0)
: std::ctype<char>(&t_[0], false, refs)
{
std::copy_n(classic_table(), table_size, t_);
t_['-'] = (mask)space;
t_['\''] = (mask)space;
t_[','] = (mask)space;
}
};
 
 
int main() {
std::istringstream input("Subway,McDonald's and Burger-King.");
std::locale x(std::locale::classic(), new Delims); // that new
// doesn't leak
input.imbue(x);
 
std::copy(std::istream_iterator<std::string>(input),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n")
);
}
 
Who uses the C++ streams for anything but for training students to think?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 09 01:49AM +0200

On 09-Jul-17 12:19 AM, jacobnavia wrote:
 
> Apparently just searches the first non blank character.
 
> How can we change the >> operator to call a user defined function to
> scan the characters?
 
The only possible customization that I recall is to define the notion of
whitespace, and I'm not even sure where to look for that.
 
But, you can overload `operator>>`, and in that overload, provide your
own custom scanning.
 
One way to do that is to define a distinct `Word` type, for use as the
overload's (second) formal argument.
 
Bypassing that complexity, you can just define an ordinary function like
 
auto word_from( istream& stream )
-> string
{
// Your custom scanning logic here.
}
 
And by /starting/ with that approach, you can at the end use it to
implement an operator>> overload, if you deem that to be desirable.
 
 
Cheers!,
 
- Alf
jacobnavia <jacob@jacob.remcomp.fr>: Jul 09 05:13PM +0200

Thanks to all for your answers
jacob
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 09 01:35AM +0200

On 08-Jul-17 11:39 PM, Christian Gollwitzer wrote:
 
> That's exactly the point. It must be fixed for Windows, maybe, because
> that is a stupid OS. For almost anything else it "just works" - why does
> Alf muck around with /proc/self and tokenize the stream etc.?
 
Because /fixing/ it for Windows, in a reliable way, appears to be
impossible. The immediate showstopper for that is that MinGW g++ doesn't
pass `__argc` and `__argv` to `main`, as Visual C++ does. But even if it
did, some other compiler might deviate from the platform convention.
 
So /stdlib/ provides an alternative, `Command_line_args`.
 
And for maximum portability until default construction of
`Command_line_args` is in place also for macOS and more OSes (hopefully
someone will help me make that happen!) I've added a portable fallback
solution, namely a factory function `Command_line_args::from_os_or_from`
(main args) that requires access to the `main` arguments. By requiring
this access it cannot be used where one does not have those `main`
arguments readily available, e.g. with a main function called by a
library supplied `main`. But on the other hand, most *nix-land code is
structured so that those arguments are accessible, proving that passing
those `main` arguments around is doable, even if unclean.
 
<url:
https://github.com/alf-p-steinbach/stdlib/#background-goal--degree-of-goal-achievement>
 
… provides some background and example programs.
 
 
Cheers & hth.,
 
- Alf
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 09 03:29AM +0100

On 09/07/2017 00:35, Alf P. Steinbach wrote:
> So /stdlib/ provides an alternative, `Command_line_args`.
 
"stdlib"? What an egregious and egotistic name for a toy hobby project
library.
 
/Flibble
Daniel <danielaparker@gmail.com>: Jul 08 07:47PM -0700

On Saturday, July 8, 2017 at 12:58:14 AM UTC-4, Mr Flibble wrote:
 
> > This works well with a convention of putting private implementation
> > stuff first in the class. :)
 
> Hardly a convention if most people put private stuff AFTER public stuff.
 
At least with that he's not a minority of one, as he is for auto main -> int
:-)
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 09 01:13AM -0500

> };
 
> is improved by private data and public accessor functions.
> That'd be some Steinbach-esque obfuscation.

That data doesn't contribute to an invariant so it's fine.
Gareth Owen <gwowen@gmail.com>: Jul 09 07:46AM +0100


> Yes, everybody agree with "int main()" being idiomatic in C++ and that Alf
> adds some redundant characters there but it is still valid C++ what he
> writes. Sort of like that "::std" of woodbrian is valid C++.
 
If there were any question of its validity, I would have chosen a word
other than "obfuscation". Obfuscation implicitly admits correctness.
"Öö Tiib" <ootiib@hot.ee>: Jul 09 05:11AM -0700

On Sunday, 9 July 2017 09:46:40 UTC+3, gwowen wrote:
> > writes. Sort of like that "::std" of woodbrian is valid C++.
 
> If there were any question of its validity, I would have chosen a word
> other than "obfuscation". Obfuscation implicitly admits correctness.
 
I did not want to imply that anyone had opinion that Alf's code is invalid.
To me obfuscated means that it is hard to read and hard to maintain and
that validity is orthogonal to it. Therefore I just noted that it is valid.
Even "obfuscation" feels somewhat too strong about it. Redundant 6
characters do not make it hard to maintain. The redundancy is at about
level of writing "if(x==true)" instead of "if(x)".
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jul 09 03:19PM +0100

On Sun, 9 Jul 2017 05:11:06 -0700 (PDT)
Öö Tiib <ootiib@hot.ee> wrote:
[snip]
> The redundancy is at about level of writing "if(x==true)" instead of
> "if(x)".
 
If 'x' is anything other than of boolean type, the first is not a
redundantly elongated version of the second. They are different. For
the naive programmer, where 'x' is an integer 'if(x==true)' might well
be a mistake. It is in any event a bad habit to get into.
asetofsymbols@gmail.com: Jul 09 02:54AM -0700

Your sys of exceptions capable of block one OS...
 
The way is clear, each function meets one error has to return one error code
 
Each function call some function has to check if the function called has found some error and in each case has to give information and answer
 
Easy
asetofsymbols@gmail.com: Jul 09 03:00AM -0700

I insert one memory in one os
it was blocked (because can not read a file?)
 
the only way that OS to answer was nothing or reboot; i think it is for C++ exceptions system...
"Öö Tiib" <ootiib@hot.ee>: Jul 09 05:16AM -0700

> it was blocked (because can not read a file?)
 
> the only way that OS to answer was nothing or reboot; i think it is for
> C++ exceptions system...
 
I can't parse what you write. May be others can? Try to write coherent
sentences.
Reinhardt Behm <rbehm@hushmail.com>: Jul 09 09:59PM +0800

AT Sunday 09 July 2017 20:16, Öö Tiib wrote:
 
>> C++ exceptions system...
 
> I can't parse what you write. May be others can? Try to write coherent
> sentences.
 
Complain to the programmer of this bot.
 
--
Reinhardt
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: