🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

6 total messages Started by Ajay Kamdar Thu, 17 Aug 1995 18:40
insert for map and multimap
#1733
Author: Ajay Kamdar
Date: Thu, 17 Aug 1995 18:40
35 lines
1705 bytes
Given a multimap, this is what I would have *liked* to do:

    multimap<int,double> m;
    m.insert(3, 5.0);

But of course, such a function does not exist. Is there a reason why
STL opted not to provide this convenient interface and chose to go
with the more tedious (for the user) approach of insert taking
a pair<const T1,T2>? Besides being convenient, it is also possible
that providing the key and the value separately rather than creating
an intermediate pair is actually more efficient.

FYI, ObjectSpace's STL<ToolKit> provides, as an extension, an insert
member function with this signature. But I would much prefer to write
code which can be ported to different STL implementations.

So I wonder why the DWP itself doesn't make calling insert easier and the
code possibly more efficient? Could someone help me understand?

I would have settled for
    m.insert(make_pair(3, 5.0));

But that doesn't work either because there is no conversion from
pair<T1,T2> to pair<const T1,T2>.


-- 
Ajay Kamdar        |    Email: ajay@lehman.com    |    Standard Disclaimer 
Lehman Brothers    |    Phone: (201) 524-5048     |


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: insert for map and multimap
#1767
Author: Klamer Schutte
Date: Fri, 18 Aug 1995 14:53
38 lines
1814 bytes
In <9508170857.ZM22058@jabba> ajay@lehman.com (Ajay Kamdar) writes:

:Given a multimap, this is what I would have *liked* to do:

:    multimap<int,double> m;
:    m.insert(3, 5.0);

:But of course, such a function does not exist. Is there a reason why
:STL opted not to provide this convenient interface and chose to go
:with the more tedious (for the user) approach of insert taking
:a pair<const T1,T2>? Besides being convenient, it is also possible
:that providing the key and the value separately rather than creating
:an intermediate pair is actually more efficient.

I also would like to see the insert member described above.

You of course can make a child class of multimap with the insert member
you want. Or you can use the function below:

template <class Key, class T, class Compare>
inline void
map_insert( multimap<Key,T,Compare > &m, const Key &k, const T &v )
{
m.insert( pair<const Key, T>(k, v) );
}

multimap<int,double,less<int> > m;

map_insert(m, 3, 5.0);

Klamer
--
Klamer Schutte	-- +31-15-786054 -- klamer@ph.tn.tudelft.nl
http://www.ph.tn.tudelft.nl/People/klamer/Klamer.html
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: insert for map and multimap
#1745
Author: John Max Skaller
Date: Sat, 19 Aug 1995 15:05
159 lines
5920 bytes
In article <9508170857.ZM22058@jabba>, Ajay Kamdar <ajay@lehman.com> wrote:
>Given a multimap, this is what I would have *liked* to do:
>
>    multimap<int,double> m;
>    m.insert(3, 5.0);
>
>But of course, such a function does not exist. Is there a reason why
>STL opted not to provide this convenient interface and chose to go
>with the more tedious (for the user) approach of insert taking
>a pair<const T1,T2>? 


	There is a tendancy I have notice amoung C++ programmers
to prefer member functions to globals. I'm going to put in an argument
for globals as the right way of doing 75% of what people usually
want members to do.

	My picture of a class is that it provides member functions
(and friends) which have a NEED to access the private implementation
details. These are called "Axioms". 

	The axioms can be said to "span" a space of potential
functionality/behaviour -- they're kind of basis vectors.
The space spanned is tha PUBLIC'ally accessible functionality
of the type: it is the set of all GLOBAL functions which can be
defined on the class.

	It is not necessary or desirable to limit the set of
member functions (and friends) to be the smallest possible set of
functions.

	Several factors ought to influence a decision to include
some functionality as a member, even when doing so does not
extend the space of functionality spanned.
 
IN FAVOUR OF BEING A MEMBER:

	1) USAGE: 
		Will the function be commonly used? 

	2) OPTIMISATION:
		 Will the function perform better if it has private access?

	3) INTERFACE COHERENCE: 
		Does the function form part of a coherent set of functions?

	4) BUILDING BLOCK:
		Does the function provide a significant combination
		of funtionality which is sufficiently
		different from other functions?

	5) Notational convenience of x.f() form

AGAINST BEING A MEMBER:

	1) MAINTAINABILITY:
		Functions with private access are harder to get right,
		and errors are less likely to attract a diagnostic:
		if a representation is changed, all member functions
		need to be examined for the impact, non-member non-friends
		will continue to work.

	2) CLUTTER:
		Lots of members clutter an interface


	3) LOSS OF POLYMORPHISM:
		Globals can work with SUBTYPES of their design type,
		and so they can apply to 

		a) other derived classes (ordinary functions)
 
		b) other types with the right looking interface
			(template functions)

	4) BREACH OF CLOSEDNESS
		Continually adding member fuctions defeats the
		purpose of encapsulation: to reduce dependence
		on implementation details to a fixed set of functions

NON-ARGUMENTS:

	1) namespace pollution. (Rubbish: we have namespaces)
	2) encapsulation (rubbish: the very idea of encapsulation
		implies a FIXED closed interface)

Here's a way to make a decision: consider a particular
representation and choose a minimal set of members to 
span the desired functionality space. Call these "axioms".

Now add in some important functions as members, call these
"theorems" -- these COULD be defined using only public
access.

Now consider another function f(): should it be a member or global?

The question to ask is: IF I CHANGED THE REPRESENTATION WOULD
A GLOBAL FUNCTION f() REMAIN EFFICIENT?

When you change the representation, of the set of existing members
"axioms" plus "theorms", some of the theorems might become
axioms and some of the axioms might become theorems -- the representation
might suggest which ought to be which for efficiency.

If some function is NEVER going to be changed when the representation
is going to change, it is a good candidate for a global.


OK: Now consider:

     
	m.insert(make_pair(3,5.0));
	m.insert(3, 5.0);

Providing BOTH these interfaces as members would be overkill.

	insert_pair(m, 3, 5.0);

is easy to implement -- and will work with ANY 
container taking a pair<> argument, saving adding this
function to every container.

	template<class Container, class Key, class Value>
	void insert_pair(Container &m, Key k, Value v) {
		m.insert(make_pair(k,v));
	}

is a possible implementation.

Note this particular implementation will work with a VECTOR as well:

	typedef VIF vector<pair<int, float> >;
	VIF x;
	insert_pair(x, 10, 4.5);

In fact, it is "portable". Because it belongs to the USER not
the container supplier.

IMHO: STL contains a reasonable set of requirements for containers:
it's a very good example of how to draw the line about 50% past
the minimal set of functions required to span the functionality
space of a container.

["50%" is merely an intuitive feeling, I haven't actually measured
the ratio theorems/axioms. A typical string class will have a higher
than usual theorem/axiom ratio because strings are heavily used
and subject to considerable optimisation depending on the implementation]

Comments?

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
	Maxtal Pty Ltd,		    
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21 
        NSW 2037, AUSTRALIA	    Phone: 61-2-566-2189

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: insert for map and multimap
#1798
Author: Ajay Kamdar
Date: Tue, 22 Aug 1995 08:10
73 lines
3587 bytes
In article <413kcm$mdu@metro.ucc.su.OZ.AU>,
John Max Skaller <maxtal@Physics.usyd.edu.au> wrote:
>In article <9508170857.ZM22058@jabba>, Ajay Kamdar <ajay@lehman.com> wrote:
>>Given a multimap, this is what I would have *liked* to do:
>>
>>    multimap<int,double> m;
>>    m.insert(3, 5.0);
>>
>>But of course, such a function does not exist. Is there a reason why
>>STL opted not to provide this convenient interface and chose to go
>>with the more tedious (for the user) approach of insert taking
>>a pair<const T1,T2>?
>
>
>	There is a tendancy I have notice amoung C++ programmers
>to prefer member functions to globals. I'm going to put in an argument
>for globals as the right way of doing 75% of what people usually
>want members to do.
>

   --- Long discussion on when a function should be global function or
       member function deleted ---


Very interesting, but I am afraid not very pertinent to *this* question.
STL already defines insert as a member function, and my question is
regarding the signature of that member function.

What I am trying to find out is why the map/multimap interface standardizes
an awkward to use interface rather than a different interface which is
easier to use and also has potential for being more efficient. Is there
a solid technical reason for the current interface of the insert function?
While we are standardizing the map/multimap, (and given that member functions
are being used in favor of global functions) what reasons are there for
not using a more natural signature for insert? I have in the past observed
a strong bias for efficiency in the active participants of the
standardization effort. So I am also hoping that there is a reason why
the potentially more efficient flavor of insert(const Key&, const Val&)
was passed over in favor of insert(const pair<const Key, Val>&).



>	insert_pair(m, 3, 5.0);
>
>is easy to implement -- and will work with ANY
>container taking a pair<> argument, saving adding this
>function to every container.
>

    --- insert_pair definition deleted ---


>In fact, it is "portable". Because it belongs to the USER not
>the container supplier.


Sure, users can write put wrappers around STL to do all sorts of useful
things. Your suggestion is very attractive. But then I can think of a couple
of other attractive solutions as well, and so will the next person, and
so on. If everyone, STL implementation vendors and users, starts inventing
their own syntax to make STL more user friendly, it appears to me that
at least some of the benefits of standardization would be lost. But then
that is a different issue...



-- 
Ajay Kamdar        |    Email: ajay@lehman.com    |    Standard Disclaimer 
Lehman Brothers    |    Phone: (201) 524-5048     |
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: insert for map and multimap
#1828
Author: Ajay Kamdar
Date: Wed, 23 Aug 1995 15:27
67 lines
3296 bytes
In article <411h8u$fi8@cyber.tn.tudelft.nl>,
Klamer Schutte <klamer@ph.tn.tudelft.nl> wrote:
>In <9508170857.ZM22058@jabba> ajay@lehman.com (Ajay Kamdar) writes:
>
>:Given a multimap, this is what I would have *liked* to do:
>
>:    multimap<int,double> m;
>:    m.insert(3, 5.0);

>
>I also would like to see the insert member described above.
>
>You of course can make a child class of multimap with the insert member
>you want. Or you can use the function below:
>
>template <class Key, class T, class Compare>
>inline void
>map_insert( multimap<Key,T,Compare > &m, const Key &k, const T &v )
>{
>m.insert( pair<const Key, T>(k, v) );
>}
>
>multimap<int,double,less<int> > m;
>
>map_insert(m, 3, 5.0);
>

Yes, there are a number of reasonable approaches to work around the problem.
But what I can't understand is why the proposed standard is the way it
is. User workarounds tend to not be compatible with each other and defeat
some of the reasons for standardizing in the first place.

It is not as if this is a very subtle usage issue which is easy to miss
when designing the interface or in experimenting it before accepting it as
a part of the DWP. The awkwardness in using insert hits anyone trying
to use a STL multimap right off the bat, starting them immediately on
inventing a workaround. For projects on which I either have direct control
or significant input, I would not propose or accept a syntax which is
so awkward to use, especially when it does not require any great expertise
to come up with an easier to use and more efficient alternative syntax.
The people who designed and approved STL have impressive design and
implementation track records. And they chose the current syntax. I find
it hard to belive that all of them dropped the ball on this. I have been
waiting with bated breath for some one to tell me that I am wrong and to
point out the reason(s) for choosing the current syntax.

I am sure some of the people directly involved in either making the
proposal or moving it through the committee are reading this. I would
very much like to hear from some of them explaining the rationale for
the current choice.

If there is really no strong rationale to support the current insert
signature other than "it is the way it is", then I would hope that
the DWP is tweaked to overcome this shortcoming.

Regards,

- Ajay


-- 
Ajay Kamdar        |    Email: ajay@lehman.com    |    Standard Disclaimer 
Lehman Brothers    |    Phone: (201) 524-5048     |

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: insert for map and multimap
#1897
Author: J. Kanze
Date: Sun, 03 Sep 1995 16:06
35 lines
1978 bytes
John Max Skaller (maxtal@suphys.physics.su.oz.au) wrote:
|> ajay@lehman.com (Ajay Kamdar) wrote:
|> >>:Given a multimap, this is what I would have *liked* to do:
|> >>
|> >>:    multimap<int,double> m;
|> >>:    m.insert(3, 5.0);
|> >
|> >But what I can't understand is why the proposed standard is the way it
|> >is.

|> Well, one reason is consistency. A container has a SINGLE kind of element,
|> in the case of map and multimap it's pair<key,value>. Thats what an iterator
|> enumerating the container contents sees. This is important in cases like:

|>     map1.insert( *map2.begin() );

|> which is very much better than

|>     pair<key,value> item = *map2.begin();
|>     map1.insert( item.first, item.second);


|> . don't you think?

But one doesn't prevent the other, does it?  Or is there some reason why
multimap::insert should not be overloaded?
-- 
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads