看似模棱两可的模板函数重载
Seemingly ambiguous template function overloads
偶然发现这个时,我试图解决的原始问题是选择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
中的表达式都应该计算为 true(skipper_type
显然不等于 unused_type
然后),并且调用应该是模棱两可的。我哪里弄错了?
这里的问题是,正如注释中的结论,当只使用 U::skp
时,可能是U
被推导为引用类型(即,在传递 lvalue 解析器时)。发生这种情况时,你会得到 SFINAE,因为引用类型显然没有嵌套任何东西。
解决方法是从U
中删除引用std::remove_reference
以便您(sizeof(std::remove_reference<T>::type::skp) != 0)
.请注意,此处不需要typename
,因为::skp
表示type
必须是类型名。
相关文章:
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- c++:可变模板和函数重载
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 解决模板成员函数重载
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 推断模板化函数中的函数重载
- C++复制函数重载导致"must be a nonstatic member function"错误
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 可变参数泛型 lambda 和函数重载
- C++中的函数重载和继承
- 当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
- C/C++ 可变参数宏函数重载
- 将基类的成员函数重载到其他派生类C++
- C++ 函数重载匹配
- C++函数重载,具体步骤是什么
- C++:使用 param pack 显式调用函数重载
- 隐式生成的函数重载用于右值参数?
- 使用函数重载输入运算符
- 运算符重载函数上的函数重载