[cfe-dev] `typename` keyword before non-type template parameter defined via nested templated `using` in out-of-line member definition

Łukasz Kucharski via cfe-dev cfe-dev at lists.llvm.org
Sun Feb 4 18:40:57 PST 2018


I hope this is a good audience.

Title seems long an convoluted, but the problem boiled down to gcc and
clang disagreeing on such code:

(This is a grokked version of code which we got during a real world
code-base evolution [if that means anything])
```
#include <type_traits>
#include <iostream>
#include <string>

template <typename T>
struct B {
    template <typename U>
    using nested_templated_using = U;

    template<typename U = T, nested_templated_using<U>* = nullptr >
    void f();
};

template <typename T>
template <typename U, typename B<T>::template nested_templated_using<U>* >
//                   ^ should typename be here or not?
void  B<T>::f(){ }

int main () { return 0;}
```
[godbolt example](https://godbolt.org/g/yjPH1u)

 clang requires `typename` keyword in the indicated spot, while gcc
forbids it. They error out with the same message indicating that the
out-of-line definition does not match declaration.

I've asked this question on
[stackoverflow](https://stackoverflow.com/questions/48448353) but it
wasn't clear yet what is the core issue, I thought gcc misbehaves.

I got some great input by Johannes Schaub, who pointed [CWG issue
#2](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2) and
[CWG issue #560](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#560).
They both treat about referring to the dependent types, though as the
type of return value.

My thoughts are:
1. The type of the parameter is dependent.
2. I am not sure whether the type of the parameter is "a member of the
current instantiation" as understood in
[temp.res#3](http://eel.is/c++draft/temp.res#3)
3. In conjunction with [temp.res#5](http://eel.is/c++draft/temp.res#5)
above renders "wrong guess" about the presence of the keyword a killer
- program is ill-formed.

I might be wrong in my toughts, and I am not sure whether, or not,
`typename` keyword usage changes for non-type template parameters.
Also, inline definition does not require the keyword.

It would be nice if someone could give authoritative answer
(preferably stepping through standard) whether:
1. clang is wrong.
2. gcc is wrong.
3. standard is unclear.

Regards,
Łukasz.



More information about the cfe-dev mailing list