これに遭遇したときに私が解決しようとした元の問題は、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
thenと等しくない)、呼び出しがあいまいになるはずです。どこが間違っているの?