Wednesday, April 29, 2020

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

Vir Campestris <vir.campestris@invalid.invalid>: Apr 29 09:49PM +0100

I've got a bit of code where I want to serialise collections of Objects.
 
I have for example
 
std::vector<Object> vec;
std::list<Object> lst;
 
It seems to me as if I should be able to write an operator<< to write
them out something like
 
template <typename Collection>
std::ostream& operator<<(
std::ostream& o,
const Collection& objects) {
for (auto e:objects)
o << e << '\t';
return o;
}
 
But I can't find a syntax that works. That one above will build - except
then the compiler can't work out which operator<< to use. I'm not
convinced it's even considering that one.
 
(I'd be happier if the parameter was a Collection<Object> for better
type safety)
 
Any ideas?
 
Andy
Juha Nieminen <nospam@thanks.invalid>: Apr 29 08:01AM

> there is some sort of significant common ground between them.
> Thirty years ago there was, but now there isn't, and it's time to
> move on.
 
At a very minimum enough compatibility would be good to maintain that
C libraries can be used directly from C++ (with a simple extern "C" {}
declaration of the C stuff).
 
Since C libraries often use more than just function declarations,
C++ still needs to support eg. C style structs, typedefs, etc.
Breaking compatibility with C libraries would be a huge setback.
Juha Nieminen <nospam@thanks.invalid>: Apr 29 08:10AM

> Certainly there are ones I didn't think of until just recently
> when I ran a piece of C code through a C++ compiler. Some of
> the obvious problems:
 
One curious difference between C and C++, which I only learned the
details of recently, is the difference in semantics of a const
variable at the global scope.
 
For example, if you have this in one compilation unit:
 
extern const char* const gName;
 
and this in another compilation unit:
 
const char* const gName = "Name";
 
and try to use that gName in that first compilation unit, in C it will
compile fine, but in C++ you'll get a linker error about "gName" not
being found.
 
The reason for this is that in C a const at the global scope has
external linkage by default, while in C++ it has internal linkage.
In other words, in C++
 
const char* const gName = "Name";
 
is the same thing as
 
static const char* const gName = "Name";
 
while in C it's not. In order to define that variable with external
linkage in C++ you have to say it explicitly:
 
extern const char* const gName = "Name";
 
(The same is true for consts inside a namespace. In this case "global scope"
also means "namespace scope".)
David Brown <david.brown@hesbynett.no>: Apr 29 11:15AM +0200

On 29/04/2020 10:10, Juha Nieminen wrote:
 
> extern const char* const gName = "Name";
 
> (The same is true for consts inside a namespace. In this case "global scope"
> also means "namespace scope".)
 
Yes. But this is easily solved by the common practice of declaring any
data that needs external linkage with an "extern" declaration in a
header file, and including that header both from the file that defines
the object, and any file that uses it.
 
(IMHO both C and C++ should have made internal linkage the default for
all data and functions from the start, and required an explicit "extern"
for external linkage, but it's far too late to fix that!)
Lynn McGuire <lynnmcguire5@gmail.com>: Apr 28 07:43PM -0500

On 4/28/2020 6:04 PM, Ian Collins wrote:
 
>> I like explicitly initializing variables since I have been so burned in
>> the past.  Just an old Fortran hacker writing C++.
 
> What did your "expert" claim is wrong with the code?
 
The string and int initializations were not allowed. Others in the
above postings said those came about in the C++2011 spec.
 
Lynn
Ian Collins <ian-news@hotmail.com>: Apr 29 12:47PM +1200

On 29/04/2020 12:43, Lynn McGuire wrote:
 
>> What did your "expert" claim is wrong with the code?
 
> The string and int initializations were not allowed. Others in the
> above postings said those came about in the C++2011 spec.
 
Okay, so Juha's guess was on the money!
 
--
Ian.
Lynn McGuire <lynnmcguire5@gmail.com>: Apr 28 08:54PM -0500

On 4/28/2020 7:47 PM, Ian Collins wrote:
 
>> The string and int initializations were not allowed.  Others in the
>> above postings said those came about in the C++2011 spec.
 
> Okay, so Juha's guess was on the money!
 
I am sorry that I did not make that clear.
 
And I got hung out by my Open Watcom pre C++2011 compiler which refused
the class variable initializations. So I got to put in a #ifndef. Lovely.
 
class ExcelSelection
{
public:
#ifndef __WATCOMC__
std::string spreadsheetName = "";
std::string sheetName = "";
std::string beginRow = "";
std::string beginColumn = "";
std::string endRow = "";
std::string endColumn = "";
bool isRange = false;
#else
std::string spreadsheetName;
std::string sheetName;
std::string beginRow;
std::string beginColumn;
std::string endRow;
std::string endColumn;
bool isRange;

No comments: