为什么结构必须与模板类位于同一名称空间中才能编译?

McL*_*ary 1 c++ gcc templates mingw

问题的标题并没有透露太多关于我的问题,但我试图用一个短语来解释这个问题.这是问题,我在Windows中使用MinGW和Linux中使用GCC编译的应用程序中有类似的代码结构.Visual Studio不会出现任何问题.结构如下:

#include <iostream>

namespace idb
{
    class Wrapper
    {
    public:
        template<typename S>
        void boo(S& s)
        {
            bind(s);
        }
    };
}

namespace idb // <- if this namespace changes, code explodes
{
    struct Fulalas
    {
        int x;
    };
}

namespace idb
{
    void bind(idb::Fulalas f)
    {
        std::cout << f.x << std::endl;
    }
}

namespace app
{
    class Foo
    {
    public:
        void func()
        {
            idb::Fulalas f;
            f.x = 5;
            w.boo(f);
        }

    private:
        idb::Wrapper w;
    };
}

int main()
{
    app::Foo f;
    f.func();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是为什么在GCC/MinGW中更改idb::Fulalasaaa::Fulalas(或任何所需名称)会产生以下错误:

..\namespace\main.cpp: In instantiation of 'void idb::Wrapper::boo(S&) [with S = aaa::Fulalas]':
..\namespace\main.cpp:41:11:   required from here
..\namespace\main.cpp:11:10: error: 'bind' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
    bind(s);
          ^
..\namespace\main.cpp:26:7: note: 'void idb::bind(aaa::Fulalas)' declared here, later in the translation unit
  void bind(aaa::Fulalas f)
Run Code Online (Sandbox Code Playgroud)

seh*_*ehe 5

这不是结构.

这是关于bind和论证依赖查找.

bind使用不合格,因此它在相关的命名空间中被查找.如果与struct绑定重载不在同一名称空间中,则不会看到/考虑它.

  • @McLeary是的.MSVC是关于两阶段查找实现的一个着名的破坏编译器(意味着模板附近的任何地方,总是,你可以依赖于名称查找是不可靠的).大多数情况下,根据标准,你获得"更多"的查找候选人而不是"合法",所以它通常不是问题,但是你可能会遇到可移植性问题. (2认同)