gpt4 book ai didi

c++ - 为什么std::visit in a unsatisfied concept会导致gcc编译错误

转载 作者:行者123 更新时间:2023-12-04 04:28:17 26 4
gpt4 key购买 nike

这段代码:

#include <concepts>
#include <string>
#include <variant>

struct any_callable {
public:
template<typename T>
void operator()(T&&) {}
};

template<typename V>
concept is_variant = requires(V v) { std::visit(any_callable{}, v); };

int main() {
constexpr bool wrapped = is_variant<std::string>;
}
不能在 gcc 11 下编译。它给出了一堆关于 valueless_by_exception 的错误诸如此类。但是,它确实在 msvc ( godbolt ) 下编译。现在,据我所知,在这种情况下,如果它通常无法编译,它将衰减为 false,否则为 true。 msvc 的行为似乎支持这一点。
所以:这是 gcc 中的错误,msvc 的非标准功能,和/或我的代码有错吗?

最佳答案

那个:

template<typename V>
concept is_variant = requires(V v) { std::visit(any_callable{}, v); };
完全有效是最近发生的变化,这是 P2162 的结果.为了使此检查工作,您需要 std::visit成为通常所说的“SFINAE-friendly”。也就是说:它必须以某种方式受到“变异性”的约束,如果 V是一个变体,它可以工作,如果 V不是变体,那么 visit从重载集中删除,使得这个调用是一个无效的表达式(这样 concept 可以被拒绝)。
但是,在 P2162 之前,对 std::visit 没有约束。 .这不是 SFINAE 友好的:调用要么有效,要么格式错误。正是这篇论文添加了一个约束,即您传递给它的类型是变体(或从一个变体)。这就是为什么您会看到您所看到的错误:调用 visit失败了,但不是以一种对 concept 友好的方式查看。
在 P2162 之后(正如论文所指出的,MSVC 已经实现,但 libstdc++ 没有实现),您的支票将有效。
但是我们可以在 C++20 中更容易地做到这一点,而无需进入变体机制 - 通过以与论文相同的方式直接检查变体性:
template<typename V>
concept is_variant = requires(V v) {
[]<typename... Ts>(std::variant<Ts...> const&){}(v);
};
该 lambda 可以用 v 调用如果 vvariant或者它继承自一个。否则,它是错误的。这比通过 visit 更直接.

关于c++ - 为什么std::visit in a unsatisfied concept会导致gcc编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68115853/

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