Generalized "using" member aliases.

161 views
Skip to first unread message

Derek Ross

unread,
Jul 21, 2016, 10:23:07 PM7/21/16
to ISO C++ Standard - Future Proposals
It would be useful if "using" aliases could be expanded beyond namespaces and types. Why not provide aliases for class members? This would be useful if you wanted to derive a class from a standard type such as pair or tuple, but wanted more meaningful member names than the built-in .first, .second, etc, names. In effect, a way to easily "rename" a member.

The member alias syntax would look like:

class X { ...
 
using NewName = ExistingName;

where ExistingName is an existing member variable or member function in a class. The implemention would treat NewName like a macro, and substitute ExistingName wherever NewName appears. ExistingName could also specify a function, e.g., "ExistingName()", in which case NewName becomes a property-like element.

Examples:

You could derive from a std::pair, then alias different names to the .first and .second members of the pair.

struct Gps_Pos : pair<double,double> {    
   
using latitude = first;
   
using longitude = second;
};

Gps_Pos gps;
gps
.latitude = 12.34; //sets gps.first

Another possibility could be to alias names to certain elements of an array. Thus, an N-dimensional array could provide names for each dimension.
 
struct Vec3d{
   
double data[3];    
   
using x = data[0];
   
using y = data[1];
   
using z = data[2];
};

Vec3d v;
v
.z = 123; // sets data[2]
 
Member aliases could also be used to shorten inconveniently long names:
 
struct My_Database{
   
int GetNumberOfCustomersCurrentlyActive(){
     
...
   
}    
   
using custs = GetNumberOfCustomersCurrentlyActive;
};
 
My_Database db;
cout
<< db.custs() ; // calls db.GetNumberOfCustomersCurrentlyActive()

Finally, member aliases could be used to access elements of a tuple through meaningful names. This brings tuples one step closer to being a struct replacement, with all the extra features that a tuple provides.

struct Person : tuple<string,int>{
   
string& get0(){return std::get<0>(*this);}
   
int&    get1(){return std::get<1>(*this);}
   
   
using name = get0();
   
using age  = get1();
};

Person p;
p
.name = "Bob"; //sets via get<0>(p)

----
Cheers,
Derek

D. B.

unread,
Jul 22, 2016, 3:40:38 AM7/22/16
to std-pr...@isocpp.org
How would one disambiguate between 'aliased members' and typenames in the outer scope, which might well overlap? Would the former now have to take precedence? What would the syntax be for resolving ambiguous aliases? I dunno, it seems like a lot of work for little benefit.

Or for negative benefit in some cases:


"ExistingName could also specify a function, e.g., "ExistingName()", in which case NewName becomes a property-like element."
- But then we have horribly ambiguous syntax for whether something is a member variable or method, requiring us to constantly consult the class to unearth byzantine using declarations, which don't produce "property-like elements" anyway if the function signature doesn't return a modifiable reference.


"Member aliases could also be used to shorten inconveniently long names"
- thereby producing 2 names for the same object, cluttering the namespace and introducing ambiguity, merely to remove the responsibility of users not to choose stupidly long names?


"This brings tuples one step closer to being a struct replacement"
- sounds like ominous portent to me. structs aren't tuples, and tuples aren't structs. Neither should replace the other. Do we really need to introduce a bunch of problems such as the above just to make interface design slightly easier for the lazy

...I dunno, just playing devil's advocate. I've never felt a need for this and am not convinced that the cited rationales are good things, quite the opposite in most cases.

Derek Ross

unread,
Jul 22, 2016, 10:58:52 AM7/22/16
to ISO C++ Standard - Future Proposals
On Friday, July 22, 2016 at 2:40:38 AM UTC-5, D. B. wrote:
How would one disambiguate between 'aliased members' and typenames in the outer scope, which might well overlap? 

It would be the same as a member variable having the same name as a type in the outer scope. So, already a solved problem. 
 
"ExistingName could also specify a function, e.g., "ExistingName()", in which case NewName becomes a property-like element."
- But then we have horribly ambiguous syntax for whether something is a member variable or method, requiring us to constantly consult the class to unearth byzantine using declarations, which don't produce "property-like elements" anyway if the function signature doesn't return a modifiable reference.

I am confident that C++ developers will be able to wrap their minds around it. 
 
"Member aliases could also be used to shorten inconveniently long names"
- thereby producing 2 names for the same object, cluttering the namespace and introducing ambiguity, merely to remove the responsibility of users not to choose stupidly long names?

This is inspired by the recommended way of shortening a long namespace name, such as 

namespace American_Telephone_and_Telegraph { ... }

using ATT = American_Telephone_and_Telegraph;

or shortening typenames like: 

using vecvecstr = std::vector<std::vector<std::string>>;
 
"This brings tuples one step closer to being a struct replacement"
- sounds like ominous portent to me. structs aren't tuples, and tuples aren't structs. Neither should replace the other. Do we really need to introduce a bunch of problems such as the above just to make interface design slightly easier for the lazy

If there were an easy way to convert a struct to a tuple, then some current topics such as reflection or default comparisons (see links), could be implemented as a library rather than by changing the language. 

 
----
Cheers, 
Derek


szollos...@gmail.com

unread,
Jul 22, 2016, 11:56:25 AM7/22/16
to ISO C++ Standard - Future Proposals
Hi,

As for the pair example, I'd suggest just using references. Note that you can have a ref to a member of a tuple as well. This might or might not have a memory cost depending on your compiler. As for the using a = b(); syntax, I'm not sure we want to 'hide' function calls behind members, as we never used to do that in C++ (that's like hidden costs). That said, I'm not completely against this, as I had this need before as well...

-lorro

Greg Marr

unread,
Jul 22, 2016, 1:58:55 PM7/22/16
to ISO C++ Standard - Future Proposals
On Thursday, July 21, 2016 at 10:23:07 PM UTC-4, Derek Ross wrote:
It would be useful if "using" aliases could be expanded beyond namespaces and types. Why not provide aliases for class members? This would be useful if you wanted to derive a class from a standard type such as pair or tuple, but wanted more meaningful member names than the built-in .first, .second, etc, names. In effect, a way to easily "rename" a member.

FrankHB1989

unread,
Jul 26, 2016, 9:47:32 PM7/26/16
to ISO C++ Standard - Future Proposals


在 2016年7月22日星期五 UTC+8下午3:40:38,D. B.写道:
How would one disambiguate between 'aliased members' and typenames in the outer scope, which might well overlap? Would the former now have to take precedence? What would the syntax be for resolving ambiguous aliases? I dunno, it seems like a lot of work for little benefit.

Or for negative benefit in some cases:

"ExistingName could also specify a function, e.g., "ExistingName()", in which case NewName becomes a property-like element."
- But then we have horribly ambiguous syntax for whether something is a member variable or method, requiring us to constantly consult the class to unearth byzantine using declarations, which don't produce "property-like elements" anyway if the function signature doesn't return a modifiable reference.

I don't see the need when you have applied some workable naming conventions.
 
"Member aliases could also be used to shorten inconveniently long names"
- thereby producing 2 names for the same object, cluttering the namespace and introducing ambiguity, merely to remove the responsibility of users not to choose stupidly long names?

Alias declarations are similar here.
 
"This brings tuples one step closer to being a struct replacement"
- sounds like ominous portent to me. structs aren't tuples, and tuples aren't structs. Neither should replace the other. Do we really need to introduce a bunch of problems such as the above just to make interface design slightly easier for the lazy

Both struct and tuple are instances of product types with possible some additional metadata. Typically, tuples are purely product types, and struts can have names in their fields, as so-called record types. Thus, structs can be viewed as tuples with (mostly) named members as its elements. The names are additional to the elements of ordinary tuple. It would be quite natural in a language with first class tuples and named member interface based on them. Also note that record types are sometimes too restrictive than necessary, e.g. specifying layout of these types should not require names of members.

 

FrankHB1989

unread,
Jul 26, 2016, 9:56:38 PM7/26/16
to ISO C++ Standard - Future Proposals


在 2016年7月23日星期六 UTC+8上午1:58:55,Greg Marr写道:
The discussion seemed to be inactive for a long time.

I actually prefer the broader idea: to allow users specifying a name in any scope bounds to some entity, rather than only in some class scope. This also eliminates some need of macros.


Reply all
Reply to author
Forward
0 new messages