1

Why does the following code generate std::bad_cast exception?

#include <iostream>
#include <regex>
#include <string>

int main()
{
    std::basic_string<char32_t> reg = U"^\\w";

    try
    {
        std::basic_regex<char32_t> tagRegex(reg);
    }
    catch(std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }

    return 0;
}

This sample on Ideone for convenience: https://ideone.com/Saea88

Using char or wchar instead of char32_t runs without throwing though (proof: https://ideone.com/OBlXed).

user3496846
  • 1,627
  • 3
  • 16
  • 28

2 Answers2

2

You can find here: http://en.cppreference.com/w/cpp/regex/regex_traits:

To use std::basic_regex with other character types (for example, char32_t), a user-provided trait class must be used.

so you would have to implement std::regex_traits<char32_t>

and to see why there is no definition for it see here: Why is there no definition for std::regex_traits<char32_t> (and thus no std::basic_regex<char32_t>) provided?

Community
  • 1
  • 1
marcinj
  • 48,511
  • 9
  • 79
  • 100
1

On GCC or Clang, the code compiles fine even with custom regex traits, but fails at runtime with std::bad_cast. If you've got yourself here, the issue comes from std::use_facet<std::ctype<char32_t>> throwing the error, because the current locale doesn't support it. You have to specialize std::ctype<char32_t> and set the global locale via std::locale::global to a new locale constructed using the old one and the specialized facet.

IS4
  • 11,945
  • 2
  • 47
  • 86
  • Could you please provide an example? – Alex Angel Mar 01 '21 at 03:16
  • @AlexAngel You can find a working implementation [here](https://github.com/IllidanS4/PawnPlus/blob/4038e8e0ae4d3a6dcd376f91466527cbee8065b7/plugins/src/modules/strings.cpp#L164) and [here](https://github.com/IllidanS4/PawnPlus/blob/4038e8e0ae4d3a6dcd376f91466527cbee8065b7/plugins/src/modules/strings.h#L356). – IS4 Mar 01 '21 at 14:11