4

Please see the following code:

struct base {};

template <class T>
struct derived : T {
  using base_type = T;
  using base_type::T;
};

int main()
{
  derived<base> x;
}

GCC accepts this code, but Clang and MSVC reject it. Who is right and why?

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Junekey Jeon
  • 1,496
  • 1
  • 11
  • 18
  • I don't know. But if this bug encourages you to write the more clear `using base_type::base_type;` or `using T::T;`, I am for it. – alfC Aug 01 '18 at 23:15
  • 1
    @alfC Ridiculously, indeed I wrote (and always write) ````using base_type::base_type````. The above code is a translation generated by the nvidia CUDA compiler (NVCC). I have no idea why NVCC makes the translation of ````base_type::base_type```` into ````base_type::T````, but that's how I encountered this issue. – Junekey Jeon Aug 02 '18 at 04:52
  • good to know. Maybe there is a way to force nvcc not to change certain parts of the code. – alfC Aug 02 '18 at 04:55

1 Answers1

5

using base_type::T; is a declaration, and the using before it is an alias. This is a bit of an edge case in the standard, since the real question boils down to where does the T get expanded. The C++ committee was referenced here as saying that they did not intend for that syntax to be valid, so LLVM explicitly removed it. It doesn't look like there's anything in the standard preventing it, so gcc isn't incorrect in allowing the conversion. Who is 'correct' is up to you.

Nicholas Pipitone
  • 4,002
  • 4
  • 24
  • 39