Topic: Any dot-operator proposals out there?
Author: "Mathias Gaunard" <loufoque@gmail.com>
Date: Thu, 1 Mar 2007 22:40:50 CST Raw View
On Feb 19, 5:13 pm, "peter koch" <peter.koch.lar...@gmail.com> wrote:
> I've occasionally wanted to be able to override the dot-operator, and
> a wish for that operator occasionally pops up in comp.lang.c++ and
> comp.lang.c++.moderated. My search for a proposal to add support for
> this operator has been without success, however, and I wonder why.
> Are there anyone here who know about any proposals supporting
> operator.? If not, do you know about anything that would prevent an
> easy implementation of said operator?
I wonder if someone ever considered allowing the class itself to
resolve the operator overloading instead of returning a pointer/
reference and resolve the operator outside.
For example,
Foo foo;
foo.something;
could turn into
Foo foo;
foo.operator.(functor());
where functor is something like this
struct functor
{
template<typename T>
inline typename T::type operator(T& t) const
{
return t.something;
}
};
and foo.bar(some, various, things);
would become
foo.operator.(functor(), some, various, things);
struct functor
{
template<typename T>
inline typename T::type operator(T& t, type_of_some&& a,
type_of_various&& b, type_of_things&& c)
{
t.bar(a, b, c);
}
};
Thus allowing more control from the class itself, because the
operation can be executed whenever the class wants.
With this, boost.variant could probably forward the operation to the
actual type, hence providing duck typing.
It could also be possible with boost.any with template virtual
functions.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Patrik Kahari" <patrik.kahari@googlemail.com>
Date: Fri, 2 Mar 2007 09:52:29 CST Raw View
On 2 Mar, 04:40, "Mathias Gaunard" <loufo...@gmail.com> wrote:
> On Feb 19, 5:13 pm, "peter koch" <peter.koch.lar...@gmail.com> wrote:
>
> > I've occasionally wanted to be able to override the dot-operator, and
> > a wish for that operator occasionally pops up in comp.lang.c++ and
> > comp.lang.c++.moderated. My search for a proposal to add support for
> > this operator has been without success, however, and I wonder why.
> > Are there anyone here who know about any proposals supporting
> > operator.? If not, do you know about anything that would prevent an
> > easy implementation of said operator?
>
> I wonder if someone ever considered allowing the class itself to
> resolve the operator overloading instead of returning a pointer/
> reference and resolve the operator outside.
>
> For example,
>
> Foo foo;
> foo.something;
>
> could turn into
>
> Foo foo;
> foo.operator.(functor());
>
> where functor is something like this
>
> struct functor
> {
> template<typename T>
> inline typename T::type operator(T& t) const
> {
> return t.something;
> }
>
> };
I dont think I understand that correctly. Wouldnt that mean that class
Foo's overload operator could only be used to get at 'something' since
'something' is hardcoded into the functor? Whatif Foo also had another
member called 'other', and what if they had the same type?
I think the underlying problem is that the pointer (or dot) operator
is unary but we would somehow like it to be binary.
So if 'foo->something' could be seen as a single operator instead of
two separate steps. Then we would not loose information about the
righthandside argument when overloading the pointer operator. (that
would solve the problem with COW wrappers. we would then know if the
righthandside is const or not)
But in C++ there probably is no way one could make the a binary
pointer operator work. In a class you would have to have a
overloadable pointer operator for every possible righthanside name
(object name and function name). But there is no way to overload a
function by the parameters name, only by its type. So there would be
no way to tell a foo.x and a foo.y appart in the binary operator if
both of these had the same type (say int).
/Regards Patrik
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Mathias Gaunard" <loufoque@gmail.com>
Date: Sat, 3 Mar 2007 14:20:59 CST Raw View
On Mar 2, 4:52 pm, "Patrik Kahari" <patrik.kah...@googlemail.com>
wrote:
> > template<typename T>
> > inline typename T::type operator(T& t) const
> > {
> > return t.something;
> > }
This obviously should have been
template<typename T>
inline typename T::type operator()(T& t) const
{
return t.something;
}
Same for the other functor example.
Also, it is probably simpler to resolve functions like this :
foo.bar(some, various, things);
would become
foo.operator.(functor(some, various, things));
struct functor
{
type_of_some&& a_;
type_of_various&& b_;
type_of_things&& c_;
functor(type_of_some&& a, type_of_various&& b, type_of_things&&
c) : a_(a), b_(b), c_(c)
{
}
template<typename T>
inline typename T::type operator()(T& t) const
{
t.bar(a_, b_, c_);
}
};
I was concerned that this could generate less optimized code but it
doesn't seem to be the case.
Thanks to that it becomes easier to write a function processing the
functor, since there is no need for variadic templates.
>
> > };
>
> I dont think I understand that correctly. Wouldnt that mean that class
> Foo's overload operator could only be used to get at 'something' since
> 'something' is hardcoded into the functor? Whatif Foo also had another
> member called 'other', and what if they had the same type?
Each call to the dot operator would create a new "anonymous" functor
type.
Of course, this generates absolutely no bloat, if everything is
properly inlined the machine code generated could be the same as a
direct call to the member.
That depends however on what operator dot decides to do with the
functor, since this mechanism would eventually allow to resolve the
operation at runtime, possibly accessing a std::map<std::string,
something> or something of the like.
What is interesting with this mechanism is the possibility of choice.
The overloaded dot operator is free to choose what to do depending on
the functor it was given. So it can choose to return the members of
the class or call its member functions, or apply those operations on
something else to act like a reference to that something, or do
something totally unrelated.
For good choice to be possible, however, the functor type needs to
expose sufficient information as static variables, like whether we're
querying a member variable or a member function, the type of the
actual call if it is a function (arity, type of the arguments), and
eventually the name as a sequence of chars. (a const char[N], or,
better, a boost::mpl::vector_c)
Since this is only some compile-time reflection, that doesn't cause
any bloat.
The only problem I see at the moment is with the return type.
I wonder if result_of or something like that could fix that issue.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: jkherciueh@gmx.net (Kai-Uwe Bux)
Date: Thu, 22 Feb 2007 18:20:25 GMT Raw View
Patrik Kahari wrote:
>> This only is a problem if one estimates that classes overloading
>> operator.() would still have other public members that client code is
>> supposed to access. I would call that hypothesis into doubt.
>
> Well, here are my two cents worth..
>
> If no addition to the public interface is allowed then the wrapper
> object is nothing more than the object it wraps as far as the client
> is concened. I think that would be a too serious limitation. A client
> could want to use such a wrapper object precicely because of the
> additional interface of the wrapper. As in the wrapper would be
> something more than the object it wraps (from the clients
> perspective).
I was thinking more of use cases where we don't want that. e.g.,
smart-references as return types of smart-pointers or proxy objects to be
returned by, say operator[] in a map. In this case, the returned object
should be as close as possible in behavior to the object it wraps.
> An example; Say a client wants to keep count of how many objects of
> some built in type are created in his system. He creates a wrapper
> type to keep a static count. He needs a public interface for clients
> to get to the count.
This particular use case is not convincing because the access to the static
count should probably happen through a static function. However, I maybe
misunderstanding; do you mean something like this:
template < typename T >
class counting_wrapper {
static
unsigned long & count ( void ) {
static unsigned long the_count = 0;
return ( the_count );
}
T the_data;
public:
counting_wrapper ( T const & val = T() )
: the_data ( val )
{
++ count();
}
counting_wrapper ( counting_wrapper const & other )
: the_data ( other.val )
{
++ count();
}
~counting_wrapper ( void ) {
-- count();
}
operator T & ( void ) {
return ( the_data );
}
operator T const & ( void ) const {
return ( the_data );
}
static
unsigned long get_count ( void ) {
return ( count() );
}
// overloaded dot-operator missing.
}; // counting_wrapper
You would just use counting_wrapper<some_type>::get_count() to get the
count. I don't see why there would be a need for a member function that
could be shadowed by overloading the dot-operator.
>> n1671 addresses that: you _can_ get at the count member, e.g, via
>> (&ws)->count. Using boost::addressof, you can do
>>
>> (addressof(ws))->count
>>
>> even when operator& is also overloaded. The proposal also discusses other
>> ways of accessing the member.
>>
>> Thus, the problem is not that certain members are inaccessible, it is
>> that getting at them requires a new batch of idioms. Since I would
>> estimate that most classes defining their own operator.() have little to
>> no use for other public members, I would be willing to put up with the
>> slight syntactic inconvenience.
>
> Having a client write (&ws)->count, instead of ws.count, would mean
> the clients would have to understand the inner workings of the wrapper
> (that the dot operator is overloaded). That seems to violate the
> principle of encapsulation.
No it does not. If the client thinks of the wrapper as _more_ than the
wrapped object, it knows that it deals with the wrapper. If the client is
written under the assumption it deals with the wrapped object, it has no
need for additional members.
> I dont think its unreasonable to excpect a uniform syntax to get to an
> objects public interface. Writing dot for most objects and having to
> write (&x)-> for others (or even (addressof(x))->) would be a
> confusing inconsistency.
As I said, I do not yet see use cases where one would overload the
dot-operator _and_ have member functions.
> The N1671 you mention has a suggested solution: "Apply operator.() if
> only there is no matching function". That sounds a reasonable solution
> to me, although there would still be a problem that functions would
> not be forwarded if there was a named function of the same name in the
> wrapper also.
If I recall correctly, n1671 recommends a different proposal. You quote from
the section "Alternative Proposals". Unless I see a convincing use case, I
would rather go with n1671 as it stands. (Although, I would not really care
that much since I do not plan on putting members other than operators
within a class that overloads the dot-operator.)
However, any of the proposals is better than not being able to overload the
dot-operator at all.
Best
Kai-Uwe Bux
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Patrik Kahari" <patrik.kahari@googlemail.com>
Date: Thu, 22 Feb 2007 15:44:12 CST Raw View
> This particular use case is not convincing because the access to the static
> count should probably happen through a static function.
Agreed, the example was no good because the wrapper only added a
static interface. I do belive there are other valid examples. I'll
have another try;
Say you make a "copy on write" wrapper class. The wrapper behaves like
the wrapped object, the only difference is that the actual wrapped
object (that you moved/copied onto the heap) can be shared by many
wrappers. When a wrapper object is copy constructed the destination
will only get a shallow copy, a full deep copy is delayed until
needed. A deep copy will be needed when the wrapped object is written
to or when its address is taken. The wrapper interface could then be
extended to allow the user to force a deep copy (on a per object
basis, as in not on a static class basis). Why would that be useful?
Say the client enters some part of his system that has multiple
threads using these objects. The user wants to make sure that the two
wrappers dont share any internal data before entering so that he wont
have to do any syncing between the two objects.
Or say that at certain times the clients system has to be fast, and at
other times the system waits around doing nothing. The user could then
use this idle time to do deep copying so that the system wont be
forced to do that the next time the system is under time preassure.
I hope this example makes better sense than the previous one.
Regards Patrik
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Kai-Uwe Bux <jkherciueh@gmx.net>
Date: Fri, 23 Feb 2007 12:09:37 CST Raw View
Patrik Kahari wrote:
>> This particular use case is not convincing because the access to the
>> static count should probably happen through a static function.
>
> Agreed, the example was no good because the wrapper only added a
> static interface. I do belive there are other valid examples. I'll
> have another try;
>
> Say you make a "copy on write" wrapper class. The wrapper behaves like
> the wrapped object, the only difference is that the actual wrapped
> object (that you moved/copied onto the heap) can be shared by many
> wrappers. When a wrapper object is copy constructed the destination
> will only get a shallow copy, a full deep copy is delayed until
> needed. A deep copy will be needed when the wrapped object is written
> to or when its address is taken.
Hm, I have doubts that a cow_wrapper is capable of making wise decisions on
when to issue a deep copy. Consider the following basic implementation
(using operator-> to forward calls):
#include <iostream>
#include <tr1/memory>
struct X {
void print ( void ) {
std::cout << "non-const\n";
}
void const_print ( void ) const {
std::cout << "const\n";
}
};
template < typename T >
class cow_wrapper {
typedef T value_type;
typedef value_type & reference;
typedef value_type const & const_reference;
typedef value_type * pointer;
typedef value_type const * const_pointer;
mutable
std::tr1::shared_ptr< value_type > the_ptr;
void make_unique ( void ) {
std::cout << "deep copy\n";
std::tr1::shared_ptr< value_type > new_ptr
( new value_type ( *the_ptr ) );
the_ptr = new_ptr;
}
public:
explicit
cow_wrapper ( const_reference val = value_type() )
: the_ptr ( new value_type ( val ) )
{}
// other methods omitted.
// using operator-> instead of dot-operator:
pointer operator-> ( void ) {
make_unique();
return ( the_ptr.operator->() );
}
const_pointer operator-> ( void ) const {
return ( the_ptr.operator->() );
}
};
int main ( void ) {
cow_wrapper<X> x;
x->const_print();
}
Running this, you will find that a deep copy is done although we just call a
const member function (so that in principle no writing should happen). The
key problem is that operator-> cannot look ahead and detect whether the
called member a const method. Whether const or non-const operator-> is
called is determined by whether the wrapper object is const or non-const.
> The wrapper interface could then be
> extended to allow the user to force a deep copy (on a per object
> basis, as in not on a static class basis). Why would that be useful?
>
> Say the client enters some part of his system that has multiple
> threads using these objects. The user wants to make sure that the two
> wrappers dont share any internal data before entering so that he wont
> have to do any syncing between the two objects.
>
> Or say that at certain times the clients system has to be fast, and at
> other times the system waits around doing nothing. The user could then
> use this idle time to do deep copying so that the system wont be
> forced to do that the next time the system is under time preassure.
>
> I hope this example makes better sense than the previous one.
Sure does. You seem to think of a member function within the wrapper class
like
deep_assign ( cow_wrapper const & other );
However, I do not see the need for such a member function. Here is how I
would go about this problem:
#include <iostream>
#include <tr1/memory>
struct X {};
template < typename T >
class cow_wrapper {
typedef T value_type;
typedef value_type & reference;
typedef value_type const & const_reference;
typedef value_type * pointer;
typedef value_type const * const_pointer;
mutable
std::tr1::shared_ptr< value_type > the_ptr;
void make_unique ( void ) {
std::cout << "deep copy\n";
std::tr1::shared_ptr< value_type > new_ptr
( new value_type ( *the_ptr ) );
the_ptr = new_ptr;
}
public:
friend
cow_wrapper deep ( cow_wrapper const & other ) {
cow_wrapper result ( other );
result.make_unique();
return ( result );
}
explicit
cow_wrapper ( const_reference val = value_type() )
: the_ptr ( new value_type ( val ) )
{}
// rest omitted
};
int main ( void ) {
cow_wrapper<X> x;
cow_wrapper<X> y ( x );
cow_wrapper<X> z ( y );
z = y;
z = x;
z = deep( x ); // as opposed to: z.deep_assign( x );
cow_wrapper<X> a ( deep( x ) );
}
The user would just say deep( ... ) whenever a deep copy or deep assignment
is needed. Note that this also allows a deep copy-constructor call, as
opposed to:
cow_wrapper<X> a;
a.deep_assign( x );
Best
Kai-Uwe Bux
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "peter koch" <peter.koch.larsen@gmail.com>
Date: Mon, 19 Feb 2007 10:13:23 CST Raw View
I've occasionally wanted to be able to override the dot-operator, and
a wish for that operator occasionally pops up in comp.lang.c++ and
comp.lang.c++.moderated. My search for a proposal to add support for
this operator has been without success, however, and I wonder why.
Are there anyone here who know about any proposals supporting
operator.? If not, do you know about anything that would prevent an
easy implementation of said operator?
/Peter
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Kai-Uwe Bux <jkherciueh@gmx.net>
Date: Mon, 19 Feb 2007 21:38:02 CST Raw View
peter koch wrote:
> I've occasionally wanted to be able to override the dot-operator, and
> a wish for that operator occasionally pops up in comp.lang.c++ and
> comp.lang.c++.moderated.
Indeed. That we cannot overload operator.() is one of my pet-peeves about
C++. I would love to have smart-references.
> My search for a proposal to add support for
> this operator has been without success, however, and I wonder why.
> Are there anyone here who know about any proposals supporting
> operator.?
Check out WG21/N1671. It's from September 2004. I do not know of any more
recent work.
> If not, do you know about anything that would prevent an
> easy implementation of said operator?
The paper contains a discussion of problems and solutions. It also states
that there was a proof of concept implementation for a previous proposal
based on gcc in the early 90s. I do not know of such an implementation for
n1671.
Best
Kai-Uwe Bux
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Patrik Kahari" <patrik.kahari@googlemail.com>
Date: Tue, 20 Feb 2007 14:54:20 CST Raw View
> I've occasionally wanted to be able to override the dot-operator [...]
> My search for a proposal to add support for this operator has been without success,
> however, and I wonder why.
Yes, In "the design and evolution of c++" Bjarne Stroustrup describes
why he did not allow it.
If i remeber correctly the resoning goes something like this;
The biggest need for a dot operator would probably be the
implementation of wrapper objects that would behave just like the
object it wrapped. As in the dot operator would return a reference to
the underlying wrapped object and not to the wrapper itself. But then
there would be no way for a client to access any methods or data of
the wrapped object itself. We can just overload the -> operator
instead and avoid the problem.
An example:
<CODE>
#include <iostream>
template <typename T>
struct Wrapper {
Wrapper(T t):t_(t), count(0) {}
T* operator->() {
++count;
return &t_;
}
/*
T& operator.() {
++count;
return t_;
}
*/
size_t count;
T t_;
};
inline void test () {
std::string s("test");
Wrapper<std::string> ws(s);
int length = ws->length();
int count = ws.count;
/* if we had overloaded the '.' operator instead of the '->' operator,
we would have no way to get access to the 'count' member */
}
</CODE>
Regards Patrik
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: jkherciueh@gmx.net (Kai-Uwe Bux)
Date: Wed, 21 Feb 2007 06:50:19 GMT Raw View
Patrik Kahari wrote:
>> I've occasionally wanted to be able to override the dot-operator [...]
>> My search for a proposal to add support for this operator has been
>> without success, however, and I wonder why.
>
> Yes, In "the design and evolution of c++" Bjarne Stroustrup describes
> why he did not allow it.
> If i remeber correctly the resoning goes something like this;
>
> The biggest need for a dot operator would probably be the
> implementation of wrapper objects that would behave just like the
> object it wrapped. As in the dot operator would return a reference to
> the underlying wrapped object and not to the wrapper itself. But then
> there would be no way for a client to access any methods or data of
> the wrapped object itself. We can just overload the -> operator
> instead and avoid the problem.
This only is a problem if one estimates that classes overloading operator.()
would still have other public members that client code is supposed to
access. I would call that hypothesis into doubt.
> An example:
>
> <CODE>
>
> #include <iostream>
>
> template <typename T>
> struct Wrapper {
> Wrapper(T t):t_(t), count(0) {}
>
> T* operator->() {
> ++count;
> return &t_;
> }
>
> /*
> T& operator.() {
> ++count;
> return t_;
> }
> */
>
> size_t count;
> T t_;
> };
>
> inline void test () {
> std::string s("test");
> Wrapper<std::string> ws(s);
> int length = ws->length();
> int count = ws.count;
> /* if we had overloaded the '.' operator instead of the '->' operator,
> we would have no way to get access to the 'count' member */
> }
>
> </CODE>
n1671 addresses that: you _can_ get at the count member, e.g, via
(&ws)->count. Using boost::addressof, you can do
(addressof(ws))->count
even when operator& is also overloaded. The proposal also discusses other
ways of accessing the member.
Thus, the problem is not that certain members are inaccessible, it is that
getting at them requires a new batch of idioms. Since I would estimate that
most classes defining their own operator.() have little to no use for other
public members, I would be willing to put up with the slight syntactic
inconvenience.
Best
Kai-Uwe Bux
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Patrik Kahari" <patrik.kahari@googlemail.com>
Date: Wed, 21 Feb 2007 09:43:59 CST Raw View
> This only is a problem if one estimates that classes overloading operator.()
> would still have other public members that client code is supposed to
> access. I would call that hypothesis into doubt.
Well, here are my two cents worth..
If no addition to the public interface is allowed then the wrapper
object is nothing more than the object it wraps as far as the client
is concened. I think that would be a too serious limitation. A client
could want to use such a wrapper object precicely because of the
additional interface of the wrapper. As in the wrapper would be
something more than the object it wraps (from the clients
perspective).
An example; Say a client wants to keep count of how many objects of
some built in type are created in his system. He creates a wrapper
type to keep a static count. He needs a public interface for clients
to get to the count.
> n1671 addresses that: you _can_ get at the count member, e.g, via
> (&ws)->count. Using boost::addressof, you can do
>
> (addressof(ws))->count
>
> even when operator& is also overloaded. The proposal also discusses other
> ways of accessing the member.
>
> Thus, the problem is not that certain members are inaccessible, it is that
> getting at them requires a new batch of idioms. Since I would estimate that
> most classes defining their own operator.() have little to no use for other
> public members, I would be willing to put up with the slight syntactic
> inconvenience.
Having a client write (&ws)->count, instead of ws.count, would mean
the clients would have to understand the inner workings of the wrapper
(that the dot operator is overloaded). That seems to violate the
principle of encapsulation.
I dont think its unreasonable to excpect a uniform syntax to get to an
objects public interface. Writing dot for most objects and having to
write (&x)-> for others (or even (addressof(x))->) would be a
confusing inconsistency.
The N1671 you mention has a suggested solution: "Apply operator.() if
only there is no matching function". That sounds a reasonable solution
to me, although there would still be a problem that functions would
not be forwarded if there was a named function of the same name in the
wrapper also.
Regards Patrik
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Patrik Kahari" <patrik.kahari@googlemail.com>
Date: Wed, 21 Feb 2007 10:24:51 CST Raw View
> An example; Say a client wants to keep count of how many objects of
> some built in type are created in his system. He creates a wrapper
> type to keep a static count. He needs a public interface for clients
> to get to the count.
Sorry, that should have been "some user defined type" and not "some
built in type" (since built in types dont use the dot operator).
Regards Patrik
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]