Topic: A nicer pair?


Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Thu, 19 Aug 2004 03:59:38 GMT
Raw View
Steven T. Hatton wrote:
> 1) The first item, alias first and second, would allow us to do things such
> as
>
> unsigned x = 7;
> unsigned y = 2;
> std::pair<unsigned, unsigned> point(x,y);
> point.alias_first("X");
> point.alias_second("Y");
>
> point.X += 20;
> point.Y += 2;

The expression "point.X" must be parsable at compile time, while you
seems to be defining aliases at runtime. How could the compiler parse
"point.X" if it doesn't know (at compile-time) what "X" is?

Even if you find a way to make such a magic happen at compile time (for
example by making alias_first() and alias_second some kind of "special
binding" methods) supporting this feature would require major
modifications in the language core and not only in the library.

> 2) The second item, constable pair<int, string> with conversion to int,
> would allow us to do things such as:

I assume that "constable" means "constant"... ;-)

> std::const_pair<1, "I"> I;
> std::const_pair<2, "J"> J;
> std::const_pair<3, "K"> K;

You are indeed suggesting to introduce a completely new class template,
as this const_pair has nothing to do with std::pair, clearly. In fact,
the std:pair template takes two types, while your const_pair seems to
take two non-types. const_pair would take an int and a const char* and
not an int and a std::string (moreover, non-type parameters can never be
of type std::string, because of 14.1/4).

Please notice that you are currently not allowed to use a literal such
as "I" as a non-type argument of a template (14.3.2/2), so the code
above is currently illegal. Again, supporting this syntax would require
a core language change.

>
> int i;
> ...
> switch(i) {
>   case I: return f_I();
>   case J: return f_J();
>   case K: return f_K();
> }

The case must be followed by an integral constant expression (6.4.2/2).
Even if "I" could be converted to int, it wouldn't make it an integral
constant expression. Again, a core language change would be needed.

> std::pair<int, std::string> X, Y, Z;
>
> X = I;
> Y = J;
> Z = K;
>

That's fairly easy:

template <int n, const char* s>
class const_pair
{
public:
   const_pair() {}
   operator int() const { return n; }
   template <typename int_type, typename string_type>
   operator std::pair<int_type, string_type>() const
   {
     return std::pair<int_type, string_type>(n, s);
   }
};

However, because you cannot solve the two problems above without a
language change, such an implementation of const_pair is fairly useless.

>
> 2,a) If we also had a feature to use these const_pairs in enum statements we
> might be able to accomplish things such as:
>
> enum color {"RED", "GREEN", "BLUE"};
> // implicity
> // const_pair(0, "RED")
> // const_pair(1, "BLUE")
> // const_pair(2, "GREEN")
>
> switch(color c) {
>   case RED:return red();
>   case GREEN: return green();
>   case BLUE: return blue();
> }
>

Again, major core language changes would be needed to make the compiler
parse the RED in "case RED:" as an integral constant. Notice that the
the token RED is never declared: lexically speaking, RED and "RED" are
two very different things!

Anyway, why can't you just use:

   enum color { RED = 0, GREEN = 1, BLUE = 2};

?

>
> 3) And the final suggestion is:
>
> std::pair::operator[](bool b) { return b?first:second; }
>

Although innocent looking, this proposal cannot be accepted either. The
problem is that first and second could be of different types, so what
would be the type of p[i] if the value of i is unknown at compile time?
The having the type of any expression known at compile time this is the
very basic of the strict type checking system over which C++ is founded.
If you allow a single hole in this system, you are de facto defining a
different language.

Regards,

Alberto

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hattons@globalsymmetry.com ("Steven T. Hatton")
Date: Mon, 9 Aug 2004 00:16:41 GMT
Raw View
Does anyone think the following modifications to std::pair would be worth
the effort?

1) Alias pair::first and pair::second

2) Constable pair<int,string> with conversion to int.
2.a) As enum tags.

3) Indexable first and second;

1) The first item, alias first and second, would allow us to do things such
as

unsigned x = 7;
unsigned y = 2;
std::pair<unsigned, unsigned> point(x,y);
point.alias_first("X");
point.alias_second("Y");

point.X += 20;
point.Y += 2;

2) The second item, constable pair<int, string> with conversion to int,
would allow us to do things such as:

std::const_pair<1, "I"> I;
std::const_pair<2, "J"> J;
std::const_pair<3, "K"> K;

int i;
...
switch(i) {
  case I: return f_I();
  case J: return f_J();
  case K: return f_K();
}

std::pair<int, std::string> X, Y, Z;

X = I;
Y = J;
Z = K;

std::cout
  << X.second << ":" X.first << std::endl
  << Y.second << ":" Y.first << std::endl
  << Z.second << ":" Z.first << std::endl;

2,a) If we also had a feature to use these const_pairs in enum statements we
might be able to accomplish things such as:

enum color {"RED", "GREEN", "BLUE"};
// implicity
// const_pair(0, "RED")
// const_pair(1, "BLUE")
// const_pair(2, "GREEN")

switch(color c) {
  case RED:return red();
  case GREEN: return green();
  case BLUE: return blue();
}

std::cout
  << RED.second   << ":" << RED.first   << std::endl
  << GREEN.second << ":" << GREEN.first << std::endl
  << BLUE.second  << ":" << BLUE.first  << std::endl;

or, more significantly,

for(color c = 0; c <= BLUE; c++){
 std::cout << color(c).second << "=" color(c).first << ", ";
}
std::cout << std::endl;

3) And the final suggestion is:

std::pair::operator[](bool b) { return b?first:second; }

For example:

typedef std::pair<int, int> face;
face xy;
face yz;
face zx;
std::vector<face> faces(3);

for(unsigned i = 0; i < faces.size(); i++) {
 faces[i][0] = f0(i);
 faces[i][1] = f1(i);
}
--
STH
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]