Overloading string literal

Q

qak

Suppose: int Buffer::put(const char *s);
Where: Put() has to find the length of 's' by strlen().
I would like to have: Put("Header Tag...") where sizeof("Header Tag...") -
1 is known at compile-time.
Macro is acceptable, but must report error if 's' is not string literal:
sizeof(s) yield size of const char*, which is not length of string.
 
M

Marcel Müller

Suppose: int Buffer::put(const char *s);
Where: Put() has to find the length of 's' by strlen().
I would like to have: Put("Header Tag...") where sizeof("Header Tag...") -
1 is known at compile-time.

#include <stdio.h>

template <size_t len>
void put(const char (&str)[len])
{ printf("%u, ", len);
fwrite(str, len, 1, stdout);
putchar('\n');
}

int main()
{ put("Test1");
put("test2\0test");
return 0;
}


Marcel
 
Q

qak

#include <stdio.h>

template <size_t len>
void put(const char (&str)[len])
{ printf("%u, ", len);
fwrite(str, len, 1, stdout);
putchar('\n');
}

int main()
{ put("Test1");
put("test2\0test");
return 0;
}

Many thanks, works perfectly for me

#include <stdio.h>

template <size_t len>
void put(const char (&str)[len])
{
printf("%u, ", len);
fwrite(str, len, 1, stdout);
putchar('\n');
}

int main()
{
const char Test[] = "TEST";
const char *Test2 = "TEST2";
put(Test);
put(Test2); // error C2784: 'void put(const char (&)[len])' :
could not deduce template argument for 'const char (&)[len]' from 'const
char *'
put("test2\0test");
return 0;
}
 
M

Marcel Müller

qak said:
#include <stdio.h>

template <size_t len>
void put(const char (&str)[len])
{
printf("%u, ", len);

%u is wrong here, the type of len is size_t.

Well, my old compiler does not know about the size type place holder.
What's wrong with std::cout? C-style printf() is quite dangerous,
especially if you don't know how to use it.

cout code looks like crap, if there are multiple parameters or explicit
format specifiers involved. And for this simple example it simply makes
no difference.

The API looks to me like someone wanted to demonstrate what could be
done with operator overloading in C++ in the early 90's.
This outputs also the zero terminator, not sure if this was the intention.

True. This was intended, to demonstrate what happens if one takes the
raw literal. The \0 may not show up on every shell, but at least the len
tells it's existence.


Marcel
 
Ö

Öö Tiib

And you repeat that for every single type that std::printf supports,
now and in the future?

I think we should have C++ printf. If for nothing else then just to silence that
boring argument. Something like in Java or like boost::format would eventually
calm it down. With variadic templates we have all the tools we need for making
type-safe printf.
 
J

James Kanze

I think we should have C++ printf. If for nothing else then
just to silence that boring argument. Something like in Java
or like boost::format would eventually calm it down. With
variadic templates we have all the tools we need for making
type-safe printf.

There's no need for variadic templates; Boost already has
boost::format (although it makes the disasterous choice of % as
the formatting operator), and long be fore that, I'd implemented
a Format class.

I suspect that the reason it doesn't make it into the standard
is that there's really no use for them. The native ostream is
more intuitive and easier to use.
 
Ö

Öö Tiib

There's no need for variadic templates; Boost already has
boost::format (although it makes the disasterous choice of % as
the formatting operator), and long be fore that, I'd implemented
a Format class.

Yes, what I meant was that with variadic templates it can look more
natural than boost::format but still have same type-safety and
support to user-defined types.
I suspect that the reason it doesn't make it into the standard
is that there's really no use for them. The native ostream is
more intuitive and easier to use.

People make and use alternatives like 'QString("%1 %2").arg(a).arg(b)'
or 'boost::format("%1% %2%") % a % b' so it must be is attractive and
elegant for their taste.
 
G

Gerhard Fiedler

Öö Tiib said:
People make and use alternatives like 'QString("%1
%2").arg(a).arg(b)' or 'boost::format("%1% %2%") % a % b' so it must
be is attractive and elegant for their taste.

Besides, it's very inconvenient to use std::eek:stream for
internationalization (the position of embedded runtime values may change
with the output language). You need something like boost::format to do
that nicely.

Gerhard
 
J

James Kanze

Besides, it's very inconvenient to use std::eek:stream for
internationalization (the position of embedded runtime values
may change with the output language). You need something like
boost::format to do that nicely.

There's nothing surprising going on here. Things like QString
or boost::format are just imitating something which sounded like
a good idea at the time. (The X/Open extensions to printf.) In
the meantime, those of us who had access to the original and
could actually try to use it realized that it wasn't such a good
idea after all. If you're trying to handle multilingual output,
neither the printf extensions nor any of its imitators help.
The difference between languages goes way beyond the order in
which you embed runtime values: you need to modify words
depending on singular or plural (or dual), or the word order
depends on the actual words, and any number of other issues. In
the end, you have to write a separate DLL for each language, or
you end up compromizing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top