
On Fri, Nov 2, 2012 at 8:36 PM, Steven Watanabe <watanabesj@gmail.com>wrote:
I haven't checked this, but it's the behavior that I would expect.
That seems surprising to me. It's a simple alias here, so I would expect it to be exactly that -- an alias. If I make a typedef of a type, I expect it to alias that type such that is_same tells me that are the same (which it, of course, does). An alias should, whenever possible, be exactly that, an alias.
Assuming that it is in fact standard, can anyone conceive of a way around this limitation? I've considered passing dummy arguments to the templates based on the template parameter list and checking that the resultant types are equal, but I'd like to avoid that if at all possible, since it seems like it would be difficult or impossible to support certain templates properly (I.E. consider the template parameter list of a template where one parameter type is dependent on another, like std::integral_constant).
You already have to specify this in the template argument list. I don't see how creating a dummy parameter makes it any worse.
Inside of the macro I know the textual form of the template parameter list, broken down into its individual parts, but not the arguments that are valid for that template. In other words, imagine a template such as this: template< class T, typename T::type X > struct foo; All I know is that parameter type 1 is "class" named "T" and that parameter type 2 is "typename T::type" named "X". I can't possibly create a proper dummy parameter automatically from within the macro since I can't deduce that the dummy type I pass to "T" is required to have a nested type called "type" that is a valid non-type template parameter type. If I get archetypes working, I should be able to build proper defaults based on the constraints of the types, but I'm not there yet and I don't think it should be necessary for this particular problem.
You have to define exactly what you mean by template aliases being equal. If you mean that for all template parameters, the aliases resolve to the same type, the problem is undecidable. (This follows directly from Rice's Theorem).
Sorry, I should have been more specific. I'm not dealing with the general case of any arbitrary template alias, I'm dealing with the special case where the template parameters of the underlying template are deducible from the template parameters of the alias. In other words, cases similar to where template argument deduction works in C++11 when dealing with a template alias: //////////////////// // A simple template template< class T > struct foo {}; // An alias where the underlying template's // parameters are deducible from the alias's // template parameters. template< class T > using foo_alias = foo< T >; // A function template taking a foo< T >, deduction works template< class T > void bar( foo< T > ); // The equivalent function written in terms of the alias template< class T > void bar_alias( foo_alias< T > ); int main() { // All of these work in C++11, as expected bar( foo< int >() ); bar( foo_alias< int >() ); bar_alias( foo< int >() ); bar_alias( foo_alias< int >() ); } //////////////////// Again, this type of deduction works when the template parameters of the underlying template are deducible from the template parameters of the alias. Similar to this behavior, it seems to me that in the case where the template parameter list of an alias is the same as its underlying template (or even to that of another alias); where the underlying template's arguments are deducible from the alias arguments; and where correspondence of the parameters to those in the underlying template are equivalent, then the alias could (IMO should) be a "true" alias (it is called an alias after all). Note that N2914 at least somewhat refers to this type of equivalence, though not in an elaborately-defined manner, when dealing with the compatibility checking of implicitly generated concept maps. -- -Matt Calabrese