4

This is a continuation of my previous question:

Can an identity alias template be a forwarding reference?

It seems that the following code works in both Clang 3.7.0 (demo) and GCC 6.0.0 (demo):

template <class T>
using forwarding_reference = T&&;

template <class T>
void foo(forwarding_reference<T>) {}

int main()
{
  int i{};
  foo(i);
  foo(1);
}

Are the compilers right to substitute the alias template for a forwarding reference and this could be a fancy way of writing one?

Community
  • 1
  • 1
Marc Andreson
  • 3,405
  • 5
  • 35
  • 51
  • 1
    How is this not exactly the same question with exactly the same answer? – Barry Apr 25 '15 at 16:43
  • 3
    @Barry This is not a duplicate. – Axalo Apr 25 '15 at 17:00
  • @MarcAndreson This is **absolutely** a duplicate. The question is: can an alias template be resolved as a forwarding reference? Columbo's answer here suggests that Angew's answer on the original question is incorrect. It would be better to have both answers in one place so that the site can have THE answer to this question - because it's a good and interesting question. – Barry Apr 25 '15 at 17:55
  • 1
    @Barry I didn't want to update an already answered question, thought it would confuse readers – Marc Andreson Apr 25 '15 at 17:56
  • 1
    clang++3.5 rejects this program btw. I remember trying this in both g++ and clang++ a while ago, and being disappointed that it didn't work in clang. It seemed like a great way to hide the `T&&` implementation detail while improving readability. It might be interesting to look for clang bug reports that mention similar issues, and if there's some discussion. – dyp Apr 26 '15 at 20:44
  • 6
    @dyp http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1700 – Piotr Skotnicki Apr 27 '15 at 06:08
  • @PiotrS. Nice find! I missed this one (I think I only looked for open ones when answering the other question, and there are enough of those related to the issue, so I didn't look further). I guess this settles it, unless (until?) some other resolution changes it indirectly... – bogdan Apr 27 '15 at 07:05

1 Answers1

4

This is indeed standard compliant. §14.5.7/2:

When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template.

Now, consider that during template argument deduction, only the type of the parameter (in terms of template parameters) is inspected - §14.8.2.1/1:

Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below.

According to the first quote, the type of the parameter, i.e. forwarding_reference<T>, is equivalent to T&&. Hence P is T&& and there can be no difference regarding deduction.

This same conclusion was made by the committee in a defect report concerning this exact scenario, #1700:

Because the types of the function parameters are the same, regardless of whether written directly or via an alias template, deduction must be handled the same way in both cases.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • Thanks, so shouldn't `identity&&` (from the previous question) work as well? We first resolve the alias template into `T&&` and then perform template argument deduction. Or is [Angew's reasoning](http://stackoverflow.com/a/29851257/391022) correct that there is additional rule which requires exactly `T&&` syntax (no matter where) to treat it as a forwarding reference? – Marc Andreson Apr 25 '15 at 17:25
  • Both compilers claim that `void foo(identity&&);` redefines `void foo(forwarding_reference);` – Marc Andreson Apr 25 '15 at 17:32
  • 1
    @MarcAndreson I believe Angew is incorrect, as `P` is defined as *"each function template parameter type (call it `P`)"* in 14.8.2.1/1. It's already **the type**, so his argument - *"`identity` is the type of the template parameter, but it is not a template parameter itself"* - seems wrong. – Columbo Apr 25 '15 at 17:32
  • @MarcAndreson (If you want I can post another answer in your previous question thread. I very much believe that `identity&&` should work fine with deduction. – Columbo Apr 25 '15 at 17:35
  • Yes please, feel free to add your answer. I'd appreciate it. – Marc Andreson Apr 25 '15 at 17:37
  • @Columbo Post this in the other thread. This question is definitely a duplicate, better to focus the conversation in the other one. – Barry Apr 25 '15 at 17:42
  • @dyp I had to rewrite the answer anyway, now it's done. – Columbo Apr 27 '15 at 15:42