7

Visual Studio 2013 (update 2) throws a compile-time error when compiling a template function who's return type is a nested type name, which has been hidden through multiple inheritance, and made visible again with the using keyword; as in the following code:

struct Base1
{
  typedef int value_type;
};

struct Base2
{
  typedef double value_type;
};

struct Derived : Base1, Base2
{
  using Base1::value_type;
};

template<typename T>
typename T::value_type nullary_function() { return 0; }

template<typename T>
typename T::value_type unary_function(T t) { return 0; }

int main()
{
  nullary_function<Derived>(); // Error: C2770
  unary_function( Derived() ); // Error: C2893
  return 0;
}

(The error numbers vary depending upon whether the function accepts template arguments or not as shown in the comments.)

G++ 4.7 accepts this code.

Specifically, I would like to know what the C++ standard has to say on the matter and whether or not this is a VC++ compiler bug. (It would appear to me that it is seeing as making nested types visible with the using keyword makes them visible in every other situation as far as I'm aware.)

I am also aware that the line with the using keyword may be changed from

using Base1::value_type;

to

typedef Base1::value_type value_type;

in order to get the code to compile and function correctly, but it seems bad for portability for some (potentially) valid code to compile on some compilers and not others - hence the desire for clarification.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
neurotempest
  • 147
  • 5
  • "it seems bad for portability" - a cynic might point out that it could be in a platform vendor's interest for code written for their platform not to be portable. But I'm sure there's a perfectly innocent reason for this compiler's idiosyncratic interpretation of the language. – Mike Seymour Aug 28 '14 at 11:21
  • The latest update is completely broken in my experience. Template deductions that worked previously now crashes the compiler! – Zoomulator Aug 28 '14 at 11:23
  • FWIW, I've had a few issues with the `using` vs. `typedef` with VS2013, they seem to not have worked all the issues out. File it as a bug on the MS Connect website and go on with the `typedef` until they fix it. You could try VS2013 update 3, the support is better but it may still not work. – Niall Aug 28 '14 at 11:23
  • 1
    In `typedef typename Base1::value_type value_type;` you don't need `typename` since `Base1` is not dependant – Antoine Aug 28 '14 at 11:23
  • Just checked, same errors on VS2013.3. Stick to the `typedef`. – Niall Aug 28 '14 at 11:26
  • @Antoine - Just noticed that myself. Thanks for pointing it out! – neurotempest Aug 28 '14 at 11:26
  • 3
    @Niall - Yeah I was planning to submit a bug for it; just wanted to get some confirmation that I'm not being an idiot first seeing as most compiler errors aren't! :) – neurotempest Aug 28 '14 at 11:28
  • Checked with VS2010 and VS2012; Exactly the same errors - Definitely not a new problem! – neurotempest Aug 28 '14 at 11:35
  • 1
    This has been submitted as a bug; [bug report here](https://connect.microsoft.com/VisualStudio/feedbackdetail/view/968574) – neurotempest Sep 10 '14 at 15:11
  • I met similar (but not the same) [problem](http://stackoverflow.com/questions/24409307/vc-2013-using-declaration-redefinition-of-member-function-leads-to-compile) – magras Oct 13 '14 at 17:44

1 Answers1

0

This is indeed a compiler bug -- ICC, CLang, and G++ all accept this code as verified on Godbolt.

The most applicable language in the standard I could find is 7.3.3 (namespace.udecl) p2 (quoted from N3337)

Every using-declaration is a declaration and a member-declaration and so can be used in a class definition.

P.S. ICC, CLang, and G++ all accept the typedef version as well.

LThode
  • 1,843
  • 1
  • 17
  • 28