473,385 Members | 1,325 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Operator...

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.
Oct 13 '08 #1
13 1737
ma***********@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
Oct 13 '08 #2
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.
Oct 13 '08 #3
ma***********@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.
Oct 13 '08 #4
ma***********@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
Oct 13 '08 #5
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
Oct 13 '08 #6
ma***********@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%2B...adic_templates
http://www.osl.iu.edu/~dgregor/cpp/v...templates.html
Oct 13 '08 #7
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.
Oct 13 '08 #8
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
Oct 14 '08 #9
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.
Oct 14 '08 #10
On Oct 14, 1:15*pm, Juha Nieminen <nos...@thanks.invalidwrote:
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

Oct 14 '08 #11
Maxim Yegorushkin wrote:
The real problem is that C++ does not have a native format mechanism.
std::ostream is just a type safety hack over snprintf()
I disagree. C++ streams are not so much about type safety (well, they
are about that too, but that's not the *only* thing), but about abstraction.

The C printf family of function are the hack, not the C++ streams.
When they designed C they had to invent *some* way of printing different
types in a way which would be as easy to use as possible. The solution
was support for variable amount of parameters to a function (which works
because C was built on stack-based architectures where such a thing is
feasible) and format strings. Then C compilers spent the next 20+ years
optimizing the runtime format string interpreters to be as fast as
possible (which they succeeded in doing pretty well in the end).

However, that doesn't make the printf functions and format strings
less of a hack, because they are just that. They are completely
non-abstract, error-prone and type-unsafe.

C++ streams are not a hack over printf. C++ streams are a
*replacement* of printf. A replacement which is intended to be
everything that the printf functions aren't, ie. abstract, type-safe and
less error-prone. They allow you to write code which safely uses streams
without having to know anything about the types being handled.

Sure, C++ streams might not be as easy to use as could be possible,
but they are definitely a step to the right direction.
and
boost::format is another hack over std::ostream. In other words, all
roads lead back into snprintf().
Wrong, all roads lead *away* from the printf family of functions,
because *those* are the real hacks, and while they may work in C, they
definitely don't work in C++. Not if you need even the slightest amount
of abstraction.
Oct 14 '08 #12
On Oct 14, 3:13*pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
On Oct 14, 1:15*pm, Juha Nieminen <nos...@thanks.invalidwrote:
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.
Except that it likely does matter.

Part of the problem is that in most programs, a single type
(e.g. double, or int) is used for values with radically
different semantics (at the user level). You want to specify
the formatting for each set of semantics program wide, however,
and not in each print statement. With iostream's, of course,
you define a manipulator for each semantics, and the job is
done. Very few other languages I've seen offer this
possibility, however, which means that you end up embedding such
critical information deep within the code at many different
places. (In well written C++, you'll almost never see any of
the standard manipulators, except perhaps std::setw. Almost
every value output will be preceded by some application specific
manipulator, however.)

In the end, the printf format specifiers are about the same as
integral or floating point literals. You don't want either in
your code.
The real problem is that C++ does not have a native format
mechanism.
Obviously, since formatting is independent of the language. As
I said above, it depends on the high level semantics of the
value. What would the native format of a double be? It just
doesn't make sense.

More generally, "formatting" is really a case where you need
double dispatch, on both the type being output, and the type of
stream it's being output to. You don't want to overcharge data
types with knowledge of how they are formatted (for twenty
different types of streams, binary and text). But of course,
the stream itself shouldn't even know of the existance of your
types.

In this regard, the solution used in iostream is pretty clever;
it leverages off the fact that the type being output doesn't
really need to be dynamically resolved, and uses overloading for
that.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 14 '08 #13
ma***********@hotmail.com kirjutas:
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);
}
As the problem with the ellipses is that one cannot pass through non-POD
objects, such an operator would presumably be just a "POD converter".
However, there are more than one way to convert something into a POD:
e.g. s.c_str(), &s, s.length(), s.empty(), etc. What you appear to want
is an operator converting a non-POD object into a POD object, which could
be passed to an ellipsis function expecting the arguments to follow the
printf() format syntax, for a specific format specifier, e.g. "%s". (Note
that if you had used "%p" instead there would have been a good chance the
code would have worked as (maybe) expected!)

This all seems very convoluted. For starters, the printf() function is
not implemented in the language proper (only in the library), but you are
advocating adding a feature for that in the language core. Second, the
ellipses may be used by other functions which are not printf-like.

So I would suggest to abandon that idea and simply just raise the
compiler warning level so it would warn you about passing non-POD-s
through the ellipses.

Regards
Paavo
Oct 16 '08 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Paul Davis | last post by:
I'd like to overload 'comma' to define a concatenation operator for integer-like classes. I've got some first ideas, but I'd appreciate a sanity check. The concatenation operator needs to so...
1
by: joesoap | last post by:
Hi can anybody please tell me what is wrong with my ostream operator??? this is the output i get using the 3 attached files. this is the output after i run assignment2 -joesoap #include...
5
by: Jason | last post by:
Hello. I am trying to learn how operator overloading works so I wrote a simple class to help me practice. I understand the basic opertoar overload like + - / *, but when I try to overload more...
0
by: Martin Magnusson | last post by:
I have defined a number of custom stream buffers with corresponding in and out streams for IO operations in my program, such as IO::output, IO::warning and IO::debug. Now, the debug stream should...
3
by: Sensei | last post by:
Hi. I have a problem with a C++ code I can't resolve, or better, I can't see what the problem should be! Here's an excerpt of the incriminated code: === bspalgo.cpp // THAT'S THE BAD...
6
by: YUY0x7 | last post by:
Hi, I am having a bit of trouble with a specialization of operator<<. Here goes: class MyStream { }; template <typename T> MyStream& operator<<(MyStream& lhs, T const &)
3
by: gugdias | last post by:
I'm coding a simple matrix class, which is resulting in the following error when compiling with g++ 3.4.2 (mingw-special): * declaration of `operator/' as non-function * expected `;' before '<'...
5
by: raylopez99 | last post by:
I need an example of a managed overloaded assignment operator for a reference class, so I can equate two classes A1 and A2, say called ARefClass, in this manner: A1=A2;. For some strange reason...
8
by: valerij | last post by:
Yes, hi How to write "operator +" and "operator =" functions in a class with a defined constructor? The following code demonstrates that I don't really understand how to do it... I think it has...
3
by: y-man | last post by:
Hi, I am trying to get an overloaded operator to work inside the class it works on. The situation is something like this: main.cc: #include "object.hh" #include "somefile.hh" object obj,...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.