C++ C++&引用;使用名称空间";追溯能见度?

C++ C++&引用;使用名称空间";追溯能见度?,c++,templates,namespaces,C++,Templates,Namespaces,我已经设置了一些代码来检测同名的方法或函数,并调用相应的方法或函数,如果两者都不存在,则调用abort。但是,我注意到,如果调用此方法的编译单元使用通过导入名称空间,则结果是无限递归,而不是中止。似乎在源文件中使用声明的正在追溯性地添加到全局名称空间,如前面的标题所示,这让我感到不安 我已尽我所能将此问题分离出来以供说明(使用MSVC2017编译): //头 名称空间ns1 { 模板 内联自动无foo__(常量U&U,int) ->decltype(foo(u)) { 返回foo(u); } 模

我已经设置了一些代码来检测同名的方法或函数,并调用相应的方法或函数,如果两者都不存在,则调用
abort
。但是,我注意到,如果调用此方法的编译单元使用通过
导入名称空间,则结果是无限递归,而不是
中止
。似乎在源文件中使用
声明的
正在追溯性地添加到全局名称空间,如前面的标题所示,这让我感到不安

我已尽我所能将此问题分离出来以供说明(使用MSVC2017编译):

//头
名称空间ns1
{
模板
内联自动无foo__(常量U&U,int)
->decltype(foo(u))
{
返回foo(u);
}
模板
内联uint64\U t foo\U free(常量U&U,字符)
{
中止();
返回0;
}
模板
内联自动foo_方法(常量U&U,int)
->decltype(u.foo())
{
返回u.foo();
}
模板
内联uint64\U t foo\U方法(常量U&U,字符)
{
返回ns1::foo_free(u,0);
}
}
名称空间ns2
{
模板
内联uint64_t foo(常量U&U)
{
返回ns1::foo_方法(u,0);
}
}
//来源
//删除此行将导致预期的行为
使用名称空间ns2;
结构类型{};
bool检测\u foo\u混淆(无效)
{
a型;
常量atype*cap=&a;
ns2::foo(cap);//问题
返回true;
}
我能想到的唯一解决方案是将
ns2::foo
或另一个
foo
命名为不同的名称,但这会对调用代码的外观产生一些不良影响

  • 这是怎么回事?
    使用名称空间
    是否总是这样工作,或者这是一个模板问题
  • 我有没有办法将
    ns1
    ns2
    分开,或者保持相同的名称

  • 如果注释
    模板内联uint64\U t foo\U free(const U&U,char)
    重载(调用
    abort()
    的函数),则在GCC和Clang都失败时生成MSVC()。因此,更大的问题就变成了:这是MSVC++编译器中的一个bug,还是正确的,GCC和Clang都有bug?@Someprogrammerdude Hm。这似乎表明其他编译器不存在这个问题。
    abort()
    函数用于将编译器错误转换为运行时错误,因此,如果MSVC编译时没有编译器错误,那么这似乎是一个bug。如果没有其他解释,我会给他们发一份bug报告。这看起来确实很奇怪。还请注意,即使在编译器资源管理器站点上提供的最新版本中也存在此“bug”。
    使用
    指令不会“导入”名称空间。它们使编译器将命名空间中的名称视为候选名称,以匹配后续代码中使用的名称。歧义是最常见的问题(using指令会导致命名空间中的名称意外地与另一个名称同样匹配)。我怀疑您正在看到一种不太常见的情况,即名称空间中的名称比其他情况下更匹配。您可以尝试使用调试器单步执行这两个版本,以确定它们之间执行流(例如调用的函数)的变化。如果对
    模板内联uint64\U t foo\U free(const U&U,char)
    重载(调用
    abort()
    的函数)进行注释,则在GCC和Clang都失败时进行MSVC构建()。因此,更大的问题就变成了:这是MSVC++编译器中的一个bug,还是正确的,GCC和Clang都有bug?@Someprogrammerdude Hm。这似乎表明其他编译器不存在这个问题。
    abort()
    函数用于将编译器错误转换为运行时错误,因此,如果MSVC编译时没有编译器错误,那么这似乎是一个bug。如果没有其他解释,我会给他们发一份bug报告。这看起来确实很奇怪。还请注意,即使在编译器资源管理器站点上提供的最新版本中也存在此“bug”。
    使用
    指令不会“导入”名称空间。它们使编译器将命名空间中的名称视为候选名称,以匹配后续代码中使用的名称。歧义是最常见的问题(using指令会导致命名空间中的名称意外地与另一个名称同样匹配)。我怀疑您正在看到一种不太常见的情况,即名称空间中的名称比其他情况下更匹配。您可以尝试使用调试器单步执行这两个版本,以确定它们之间的执行流(例如调用的函数)在何处发生更改。