谁在这里是正确的,GCC 还是 MSVC?

Who is correct here, GCC or MSVC?

假设我们有这样的结构:

namespace some_namespace::types {
    using foo_t = int;
}

namespace some_namespace::classes {
    class bar {
    public:
        auto do_stuff() -> types::foo_t;
    };
}

using namespace some_namespace::classes;

auto bar::do_stuff() -> types::foo_t {
    return 1;
}

这段代码可以在 GCC6 中顺利编译。
另一方面,启用 /std:c++latest 开关的 VS15 无法识别 do_stuff 的 return 类型。它 returns C2653.

现在,我觉得非常可疑的是,通过将下半部分更改为以下内容可以解决此问题:

using namespace some_namespace;

auto classes::bar::do_stuff() -> types::foo_t {
    return 1;
}

这在我眼里应该是相等的。我是否误以为这是一个 MSVC 错误?标准对此有何规定?

这与 C++17 功能无关,它没有涉及 using-directives,实际上也与 using-directives 无关。 MSVC 从

产生相同的错误
namespace some_namespace{
    namespace types {
        using foo_t = int;
    }
    namespace classes {
        class bar {
        public:
            auto do_stuff() -> types::foo_t;
        };
    }
}

using some_namespace::classes::bar;

auto bar::do_stuff() -> types::foo_t {
    return 1;
}

[basic.lookup.unqual]/8:

For the members of a class X, a name used [...] in the definition of a class member outside of the definition of X, following the member's declarator-id, shall be declared in one of the following ways:

  • before its use in the block in which it is used or in an enclosing block ([stmt.block]), or

  • shall be a member of class X or be a member of a base class of X ([class.member.lookup]), or

  • [...two bullet points about nested and local classes omitted...]

  • if X is a member of namespace N [...], before the use of the name, in namespace N or in one of N's enclosing namespaces.

types 的名称查找应首先在 bar 内部查找,然后在 classes 内部查找,然后在 some_namespace 内部查找。最后一个应该找到命名空间 types.