2

I'm writing a class with a std::regex member:

class aaa {
    std::regex re {"aaabbb"};
public:
    aaa() {}
   ...
};

The std::regex can throw a std::regex_error if the string passed in is not a valid regular expression. Is there a technique in C++11/14 to catch this exception within the class?

similar to this:

class aaa {
    std::regex re;
public:
    aaa() 
    try 
       : re("aaabbb") {
    }
    catch(...) {
    }
};
Barry
  • 286,269
  • 29
  • 621
  • 977
amigo421
  • 2,429
  • 4
  • 26
  • 55
  • 2
    And what is wrong with the latter method? That is a [perfectly acceptable way](https://stackoverflow.com/questions/160147/catching-exceptions-from-a-constructors-initializer-list) to catch the exception. – Cory Kramer Jun 23 '15 at 18:03
  • @CoryKramer It is not the member initializer he is looking for. – Baum mit Augen Jun 23 '15 at 18:08
  • second way is acceptable, I just want to understand - new standards allows an initialization in member declaration but doesn't do any steps for exception handling for this way? – amigo421 Jun 23 '15 at 18:34
  • @amigo421: You can log the exception, and/or throw some other exception. Isn't that enough? Would you like to *ignore* any failure and just carry on? That's the approach used in many scripting languages as well as e.g. the Windows Graphics Device Interface, but it's not common in C++. – Cheers and hth. - Alf Jun 23 '15 at 18:39

2 Answers2

4

You actually can not catch an exception without a rethrow (which is implicit), if an exception occurs in the initializer list:

include <stdexcept>

struct E { E(int) { throw std::runtime_error("E"); } };
class A {
    E e {1};
public:
    A()
    try
    {}
    catch(...) {
        std::cout << "Exception" << std::endl;
    }
};
int main()
{
    A a;
    return 0;
}

Gives:

Exception
terminate called after throwing an instance of 'std::runtime_error'
  what():  E
Aborted

However, you can catch it, even without mentioning the member in the initializer list.

Hence, you may have an exception safe initialization of the member and handle exception critical assignment/initialization inside the constructors body (as other (deleted) answers suggested).

  • do you mean that exception during the initialization in place of declaration anyway will be catched up in ctor like you wrote? let me check, I can't believe in this – amigo421 Jun 23 '15 at 18:40
  • for the case of the processing in ctor body, your class E should have default ctor (for declaring this as a memeber of A) , but - if default ctor of E exists with the same code - throws the exception, this can't be completely catched up in A ctor body and rethrowed again – amigo421 Jun 23 '15 at 19:02
  • @amigo421 If a member has not a non-throwing constructor, bad luck ;-( –  Jun 23 '15 at 19:12
  • seems the deleted answer (yes, I saw this, and didn't understand why the shared_ptr was used there) showed the only right way for such cases: using shared_ptr for declaring members with possible exceptions in ctors – amigo421 Jun 23 '15 at 19:27
  • 1
    @amigo421 the shared pointer is overkill - just have an empty regex –  Jun 23 '15 at 19:29
1

There might be a fancier way to do it, but I'd just have std::regex re; be declared as a class member variable, and try to initialize it in the default and/or other constructors. Then you could handle the exception within the constructor.

RyanP
  • 1,898
  • 15
  • 20