I've been searching and experimenting and I can't figure out if the MSVC compiler is wrong or I'm doing something wrong.

I've simplified the case down to a minimal set of declarations that don't require any included headers:

// A namespace.
namespace TestNamespace
{
  // And a class inside that.
  class TestClass
  {
  private:
    // Note that we're private
    struct NestedEnum {
      enum type {
        First,
        Second,
        Third,
      };
    };

    // Test friend declaration.
    friend void operator<<(int, const NestedEnum::type);
  };

  // Actual declaration.  It can't be earlier because of NestedEnum.
  void operator<<(int, const TestClass::NestedEnum::type);
}

// Actual definition, outside of the TestNamespace block, but scoped to be
// in the namespace.
void TestNamespace::operator<<(int, const TestClass::NestedEnum::type)
{}

With MSVC, I get:

cl.exe foo.cc
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

foo.cc
foo.cc(27) : error C2248: 'TestNamespace::TestClass::NestedEnum' : cannot access private struct declared in class 'TestNamespace::TestClass'
    foo.cc(9) : see declaration of 'TestNamespace::TestClass::NestedEnum'
    foo.cc(6) : see declaration of 'TestNamespace::TestClass'

Both gcc 4.7.2 and clang-425.0.28 accept this (and the more complex real example this is based on).

有帮助吗?

解决方案

As per Rastaban's comment, this is a bug in the compiler.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top