首页 > 解决方案 > MSVC - 在通用 lambda 的调用者中使用命名空间指令泄漏到 lambda 的主体中

问题描述

考虑以下玩具代码:

#include <boost/hana/transform.hpp>
#include <range/v3/view/transform.hpp>

auto constexpr f = [](auto) {
    using namespace ranges::views;
    auto xxx = transform;
};

void caller() {
    using boost::hana::transform;
    f(1);
}

它使用 GCC 和 MS 的编译器编译得很好,这意味着它using boost::hana::transform;不会影响f' 正文中可用的名称,所以它是明确xxxranges::views::transform.

另一方面,如果我更改using boost::hana::transform;using namespace boost::hana;,则 Visual Studio 声称transforminf的 body 是一个模棱两可的名称。

这是 GCC 或 Visual Studio 中的错误吗?这是一个已知的错误吗?这是因为什么?

这是一个小例子(运行它):

#include <boost/hana/transform.hpp>
#include <range/v3/view/transform.hpp>

auto constexpr f = [](auto) {
    using namespace ranges::views;
    auto xxx = transform;
};

void caller() {
#if 1
    using namespace boost::hana;
#else
    using boost::hana::transform;
#endif
    f(1);
}

标签: c++visual-studiocompiler-errorsc++17language-lawyer

解决方案


这是一个与通用lambda 相关的 MSVC 错误。一个最小的例子是

void foo() {}

namespace B {
   void foo() {}
}

auto moo = [](auto) {
   foo();
};

int main() {
   using namespace B;
   moo(1);
}

它使用 c++17 和 c++20 设置进行复制。

众所周知,MSVC 对模板实例化和两阶段名称查找有不一致的处理。这些错误中有许多已在最新版本的编译器中得到修复,但显然不是全部。在这里,在moo实例化之后,名称foo显然是在实例化上下文中查找的。这不应该发生,因为它不是从属名称。


推荐阅读