[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Operator...

martyn_dobson

10/13/2008 10:11:00 AM

this has probably been asked/suggested many timtes before, but i just
thought of it.

why is there no such thing as something like operator...()
imho it would allow us to smooth off one of the sharper corners of c+
+.

you could maybe do something like this:

class string
{
public:

const char *operator...() const
{
return c_str();
}
};


void foo(const char *format, ...)
{
//the usual vaarg stuff
}


void bar()
{
string s = "test";

foo("this is a test %s", s);
}



just a quick thought,

M.
13 Answers

Victor Bazarov

10/13/2008 12:50:00 PM

0

martyn_dobson@hotmail.com wrote:
> this has probably been asked/suggested many timtes before, but i just
> thought of it.
>
> why is there no such thing as something like operator...()
> imho it would allow us to smooth off one of the sharper corners of c+
> +.
>
> you could maybe do something like this:
>
> class string
> {
> public:
>
> const char *operator...() const
> {
> return c_str();
> }
> };
>
>
> void foo(const char *format, ...)
> {
> //the usual vaarg stuff
> }
>
>
> void bar()
> {
> string s = "test";
>
> foo("this is a test %s", s);
> }
>
>
>
> just a quick thought,

Well, on the first glance it looked OK, but then I thought, so why can't
you just do

foo("this is a test %s", s.c_str());

? It would accomplish the exactly same thing without changing the
language. Do you think you could give an example that couldn't be
countered by a use of a static_cast<> or a member function that already
exists?

Generally speaking, you're promoting the lowest rank conversion operator
which can be used when no other standard or user-defined conversion is
suitable, I am guessing. Since I don't use conversions that much I
can't really immediately see where else (aside from the actual '...') it
would be useful.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

martyn_dobson

10/13/2008 4:35:00 PM

0

yeah the standard thing is to have to call s.c_str().
the standards board purposefully didnt put an operator char* into
string for the reason that you cant make the std::string class act
entirely like a pod type like in other languages because of variable
arguments.

i meant this only as a possible conversion for a class beign passed
into a variable argument parameter list. its one of those things that
catches people out, and makes other programmers wonder why c++ isnt
more helpfull some times.

just thought it could be a handy little addition.

M.

Juha Nieminen

10/13/2008 4:39:00 PM

0

martyn_dobson@hotmail.com wrote:
> this has probably been asked/suggested many timtes before, but i just
> thought of it.
>
> why is there no such thing as something like operator...()
> imho it would allow us to smooth off one of the sharper corners of c+
> +.

The next C++ standard will introduce variadic templates, which will
allow writing type-safe functions which take a variable amount of
parameters. I believe that will allow you to do what you are referring
to here.

Victor Bazarov

10/13/2008 4:44:00 PM

0

martyn_dobson@hotmail.com wrote:
> yeah the standard thing is to have to call s.c_str().
> the standards board purposefully didnt put an operator char* into
> string for the reason that you cant make the std::string class act
> entirely like a pod type like in other languages because of variable
> arguments.
>
> i meant this only as a possible conversion for a class beign passed
> into a variable argument parameter list. its one of those things that
> catches people out, and makes other programmers wonder why c++ isnt
> more helpfull some times.
>
> just thought it could be a handy little addition.

The problem with "handy little" additions like that is that they aren't
as little as you might think. It's not always easy to find the right
balance, it seems. If you only say that 'operator...' is used where the
object is passed to the function with variable number of arguments, then
the usefulness of that addition is really questionable. If you try to
extend the scope of the change to, say, include any possible conversion
that is not otherwise explicitly specified, then all the potential areas
that the change is going to affect suddenly become hard to enumerate.

I would say that at this point on C++ development as a language, it is
unlikely that such a narrowly scoped addition is going to be adopted.
OTOH, it would be nice, perhaps, to amend the language to actually
specify what conversion is going to be used when an object or a
reference to an object is passed to the function with ellipsis, instead
of just saying essentially nothing (by hiding behind UB excuse).

Post to comp.lang.c++.moderated (and write it up a bit more
specifically), see what reaction you get. Some folks do not read the
non-moderated forum (why, beats me), and you might actually want their
input.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Maxim Yegorushkin

10/13/2008 4:48:00 PM

0

On Oct 13, 11:10 am, martyn_dob...@hotmail.com wrote:
> this has probably been asked/suggested many timtes before, but i just
> thought of it.
>
> why is there no such thing as something like operator...()
> imho it would allow us to smooth off one of the sharper corners of c+
> +.
>
> you could maybe do something like this:
>
> class string
> {
> public:
>
>         const char *operator...() const
>         {
>                 return c_str();
>         }
> };
>
> void foo(const char *format, ...)
> {
>         //the usual vaarg stuff
>
> }
>
> void bar()
> {
>         string s = "test";
>         foo("this is a test %s", s);
> }

I quite like format strings myself because of its concise syntax.
However, C++ objects do not like to be passed into "...".

The shortest syntax for passing C++ objects into "..." along with
formatting them into automatically allocated buffers is prefixing
objects with an overloaded operator~() (binary negation). This
overloaded operator allocates a temporary buffer on the stack, formats
an object into that buffer and returns an argument for "%.*s" format
string. Obviously, the buffer is only alive till until the full
expression has been evaluated.

Please scroll down to main() first to see usage:

#include <stdio.h>

// hack: supposed to be layout compatible with arguments for
"%.*s"
struct StarString
{
int n;
char* p;
};

struct TmpBuf
{
char buf[0x100];
StarString format_arg;

template<class T>
TmpBuf(T const& t)
{
format_arg.n = sizeof buf;
format_arg.p = buf;
format_arg = t.format(format_arg);
};
};

StarString operator~(TmpBuf const& buf)
{
return buf.format_arg;
}

struct Y
{
StarString format(StarString s) const
{
s.p = "Hello world from Y";
s.n = sizeof "Hello world from Y" - 1;
return s;
}
};

struct X
{
StarString format(StarString s) const
{
s.n = snprintf(s.p, s.n, "X@%p", this);
return s;
}
};

int main()
{
// what ~Y() does:
// 1) creates a temporary Y object
// 2) creates a temporary TmpBuf object
// 3) calls Y::format() to format the Y object into the
buffer provided by TmpBuf
// 4) return StarString which is passed into %.*s instead of
(int, char*).
printf("%.*s\n", ~Y());
printf("%.*s\n", ~X());
}

--
Max

Jeff Schwab

10/13/2008 4:57:00 PM

0

martyn_dobson@hotmail.com wrote:
> this has probably been asked/suggested many timtes before, but i just
> thought of it.
>
> why is there no such thing as something like operator...()
> imho it would allow us to smooth off one of the sharper corners of c++.

The variadic templates in C++0x should provide the same benefit, but in
a more generic way. They use the ... syntax. If you're comfortable
with templates, I think you've got your wish.

http://en.wikipedia.org/wiki/C%2B%2B0x#Variadic...
http://www.osl.iu.edu/~dgregor/cpp/variadic-temp...

Ioannis Vranos

10/13/2008 6:02:00 PM

0

Maxim Yegorushkin wrote:
>
> [...]
>
> struct X
> {
> StarString format(StarString s) const
> {
> s.n = snprintf(s.p, s.n, "X@%p", this);


There isn't any snprintf in C++98/03.

Maxim Yegorushkin

10/14/2008 8:12:00 AM

0

On Oct 13, 7:02 pm, Ioannis Vranos <ivra...@no.spam.nospamfreemail.gr>
wrote:
> Maxim Yegorushkin wrote:
>
> >     [...]
>
> >     struct X
> >     {
> >         StarString format(StarString s) const
> >         {
> >             s.n = snprintf(s.p, s.n, "X@%p", this);
>
> There isn't any snprintf in C++98/03.

Too bad for the standard ;)))

--
Max

Juha Nieminen

10/14/2008 12:16:00 PM

0

Maxim Yegorushkin wrote:
> I quite like format strings myself because of its concise syntax.

The major problem with printf-style format strings is that they are
not very abstract. This means that it's very hard to abstract away some
type because the format string needs to know the exact type, as a string
(rather than as an overloaded function or whatever).

I think this example illustrates perfectly the problem with format
strings:

template<typename T>
void foo(const T& value)
{
std::cout << value << "\n"; // ok

std::printf("%???\n", value); // What to put here???
}

Of course templated functions are not the only situation where the
lack of abstraction of format strings can hit you hard. It's enough to
have typedeffed some type, which you later want to print. (Sure, you can
try to struggle by also #defining the format string for that type, but
that's awkward and has a multitude of problems in itself.)

If I'm not mistaken, the next C++ standard will introduce a feature
which will allow an abstract and type-safe way of giving a variable
amount of parameters to a function, with the so-called variadic templates.

Maxim Yegorushkin

10/14/2008 1:13:00 PM

0

On Oct 14, 1:15 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Maxim Yegorushkin wrote:
> > I quite like format strings myself because of its concise syntax.
>
>   The major problem with printf-style format strings is that they are
> not very abstract. This means that it's very hard to abstract away some
> type because the format string needs to know the exact type, as a string
> (rather than as an overloaded function or whatever).
>
>   I think this example illustrates perfectly the problem with format
> strings:
>
> template<typename T>
> void foo(const T& value)
> {
>     std::cout << value << "\n"; // ok
>     std::printf("%???\n", value); // What to put here???
> }

You put %s in there because it does not matter what you are
outputting, what does matter is that you want to have a textual form
of it.

The real problem is that C++ does not have a native format mechanism.
std::ostream is just a type safety hack over snprintf() and
boost::format is another hack over std::ostream. In other words, all
roads lead back into snprintf().

My dream high-performance C++ formatting mechanism would represent the
output sequence as an iterator and formatting would emit symbols
directly into the iterator.

--
Max