gpt4 book ai didi

c++ - 看似模棱两可的模板函数重载

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:30:31 24 4
gpt4 key购买 nike

当我偶然发现这个问题时,我最初试图解决的问题是选择 parse_impl 版本:

  • 如果解析器(U 类型)提供了一个名为"skp" 的字段,则使用该字段;
  • 如果不是,则使用默认值。

我想出了以下代码:

// This variant compiles for parsers requiring a skipper:
template <typename I, typename U, typename A,
typename = typename std::enable_if<
not std::is_same<
typename std::remove_reference<U>::type::skipper_type,
qi::unused_type
>::value
>::type,
typename = void > // avoid redefinition (1 more overload not shown)
bool parse_impl(I & start, I end, U && parser, A & attr)
{
// qi::space by default:
return qi::phrase_parse(start, end, parser, qi::space, attr);
}

// This variant compiles for parsers providing skipper via 'skp' member:
template <typename I, typename U, typename A,
typename = typename std::enable_if<
not std::is_same<
typename std::remove_reference<U>::type::skipper_type,
qi::unused_type
>::value
&& (sizeof(U::skp) != 0)
>::type,
typename = void, typename = void > // avoid redefinition
bool parse_impl(I & start, I end, U && parser, A & attr)
{
// parser.skp is available:
return qi::phrase_parse(start, end, parser, parser.skp, attr);
}

调用站点如下所示:

pr.is_ok = parse_impl(pr.position, input.cend(), parser, pr.attr);

对于具有 skp 和没有的类型都会调用此方法。

它编译(在 gcc4.7 上),但我不明白为什么:当存在 skp 时,两个 enable_if 中的表达式的计算结果应该为真( skipper_type 显然不等于 unused_type 那么),调用应该是有歧义的。我哪里错了?

最佳答案

这里的问题是,正如评论中总结的那样,当仅使用 U::skp 时,可能是 U被推断为引用类型(即,传递左值解析器时)。发生这种情况时,您将启动 SFINAE,因为引用类型显然没有嵌套任何东西

解决方法是从 U 中删除引用与 std::remove_reference这样你就有了(sizeof(std::remove_reference<T>::type::skp) != 0) .注意 typename这里不需要,因为 ::skp表示 type必须是类型名称。

关于c++ - 看似模棱两可的模板函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12924402/

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