gpt4 book ai didi

C++ MSVC/GCC/Clang 编译器错误

转载 作者:搜寻专家 更新时间:2023-10-31 00:28:44 25 4
gpt4 key购买 nike

我从标题中发现了 3 个编译器中似乎令人心碎的错误。以下代码使用 c++11 和 c++14 标准的所有三个编译器的最新版本进行编译,尽管它确实不应该因为“visit_detail”函数对“main”不可见。

更正:我是愚蠢的,实际上不是 GCC/Clang 中的错误,但似乎是我的 MSVC 版本中的错误。

#include <utility>
#include <iostream>
#include <type_traits>



namespace bug
{
using namespace std;
using size_t = unsigned long long;



namespace detail
{
struct visit_stop_t {};
constexpr bug::detail::visit_stop_t visit_stop = bug::detail::visit_stop_t();



template <typename Visitor, typename First, typename... Tail>
void visit_detail(Visitor&& vis, First&& first, Tail&&... tail)
{
// code, not necessairy to recreate bug
}
}


template <typename Visitor, typename... Variants>
void visit(Visitor&& vis, Variants&&... vars)
{
bug::detail::visit_detail(bug::forward<Visitor>(vis), bug::forward<Variants>(vars)..., bug::detail::visit_stop);
}

template <typename Visitor>
void visit(Visitor&& vis) = delete;
}

using namespace bug;



// dummy variant, used to test the code
// code is never actually used in this version
template <typename... T>
struct variant
{
static constexpr bug::size_t size() noexcept { return sizeof...(T); }


constexpr variant(int) noexcept {}

template <bug::size_t I>
constexpr int get() const noexcept { return 5; }
};

// simple example visitor
// code is never actually used in this version
struct visitor
{
int operator()(int x) { std::cout << x << std::endl; return x; }
double operator()(double x) { std::cout << x << std::endl; return x; }
};



int main()
{
visitor vis;
variant<int, double> var = 5;

// where the trouble is:
visit_detail(vis, var, bug::detail::visit_stop); // ADL: http://en.cppreference.com/w/cpp/language/adl
visit_detail(vis, var); // fails with GCC/Clang, no error with MSVC => MSVC bug maybe


std::cout << "Press enter to continue . . . ";
std::getchar();
return 0;
}

最佳答案

您遇到的是一个名为 argument-dependent lookup 的 C++ 功能,或简称 ADL。基本上,如果你调用一个函数 f如果不明确限定它,编译器将查找 f在您传递的参数的命名空间中。

这就是允许 operator<< 的原因让 IO 流无需资格即可工作:

std::cout << 100; // finds std::operator<<(std::ostream&, int);

在您的特定情况下,参数 bug::detail::visit_stop正在让编译器寻找 visit_detailbug::detail里面命名空间。

关于C++ MSVC/GCC/Clang 编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44028261/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com