У меня есть работающий синтаксический анализатор 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 */
);
Этот код компилирует и правильно анализирует мой тестовый ввод, как на лязг и на г ++.
Поскольку две специализации переменных переменных зависят от параметра шаблона в одной и той же форме, я хочу объединить их в шаблон общей переменной:
template<class Format>
auto const position = attribute_cast<ast::position<Format>>
(
/* code depending on Format, omitted for brevity */
);
Это также компилирует и анализирует правильно для г ++. Он также компилируется для Clang, но корректно анализирует только мой ввод Wandbox, и не на Coliru. На моем собственном устройстве dev, с clang-3.8.0 от apt.llvm.org, Я получаю такое же ошибочное поведение, как и на Колиру.
Вопрос: Есть ли ошибка в Clang для специализации переменных шаблонов? Как я могу настроить Clang так же, как на Wandbox, чтобы обойти эту ошибку? Или это как-то ошибка, связанная с Spirit-X3?
После тестирования других компиляторов это выглядит ошибка генерации кода шаблона переменной в 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.
Других решений пока нет …