Парсеры Spirit-X3, хранящиеся в переменных шаблонах, не работают на Clang
У меня есть работающий синтаксический анализатор Spirit-X3, который может анализировать две тесно связанные грамматики для настройки положений черновиков и шашек. Я определяю две переменные специализации шаблонов как парсеры для двух диалектов грамматики:
// general variable template
template<class Format>
auto const position = []{};
// template specialization for algebraic notation (squares of the form "a1"-"h8")
template<>
auto const position<ast::ALG> = attribute_cast<ast::position<ast::ALG>>
(
/* code depending on ast::ALG, omitted for brevity */
);
// template specialization for numeric notation (squares numbered 1 through N)
template<>
auto const position<ast::NUM> = attribute_cast<ast::position<ast::NUM>>
(
/* code depending on ast::NUM, omitted for brevity */
);
Этот код компилирует и корректно анализирует мой тестовый ввод, как на Clang, так и на g ++.
Поскольку две специализации переменных переменных зависят от параметра шаблона в одной и той же форме, я хочу объединить их в шаблон общей переменной:
template<class Format>
auto const position = attribute_cast<ast::position<Format>>
(
/* code depending on Format, omitted for brevity */
);
Это также компилирует и анализирует правильно для g ++. Он также компилируется для Clang, но корректно анализирует только мои данные в Wandbox, а не в Coliru. На моем собственном устройстве разработчика с clang-3.8.0 от http://apt.llvm.org/ я получаю то же ошибочное поведение, что и на Coliru.
Вопрос: есть ли ошибка в Clang для специализации переменных шаблонов? Как я могу настроить Clang так же, как на Wandbox, чтобы обойти эту ошибку? Или это как-то ошибка, связанная с Spirit-X3?
1 ответ
После тестирования других компиляторов в Clang возникает ошибка генерации кода шаблона переменной, так как код правильно разбирает все в g++.
В дополнение к явной специализации snafu, приведенной выше, Clang также дросселирует (то есть компилирует, но выдает неверный код, который не может проанализировать ввод) в синтаксических анализаторах Spirit-X3 с переменными шаблонами, которые не были явно специализированы:
template<class Format>
auto piece_list = piece >> file >> rank;
template<>
auto const piece_list<ast::NUM> = piece >> square >> -('-' >> square);
Живой пример здесь, который только анализирует строки позиции в числовой форме и неправильно обрабатывает все алгебраические строки (для которых не было дано явной специализации).
и работает, только если шаблон общей переменной специализирован для всех случаев, которые будут вызваны:
template<class Format>
auto piece_list = 0;
template<>
auto const piece_list<ast::ALG> = piece >> file >> rank;
template<>
auto const piece_list<ast::NUM> = piece >> square >> -('-' >> square);
Я не смог найти небольшой уменьшенный тестовый пример, который изолировал бы ошибку Clang.