Check balanced brackets in a text
This is looking pretty good! But there is definitely room for improvement:

Better template parameter name

T generally refers to "any type". Since your template is based on a character type, you should use something like CharT to be more explicit.

Is there really a reason for this to be mutable?

addBracketPairs(), removeBracketPairs() and clearBracketPairs() is just extraneous api surface to me. 

I would personally have favored a public API consisting entirely of:


Construct a brackets matcher.
Use the bracket matcher to match brackets.
MAYBE have a join() function to combine two matchers together into 1.


On the surface, it looks less flexible, but it's as functional as your version, and takes a fraction of the time to wrap your head around.

It also means that your emptiness check can be moved to the constructor, so that you don't have to perform that check every single time isBalanced() is invoked.

isBalanced() should take a pair of iterators.

The correct signature for isBalanced() is:


template&lt;typename IteT&gt;
bool isBalanced(IteT begin, IteT end) const;


This way, you can consume from vectors, strings, character arrays, etc... and there is no need to make a copy of the data into a vector prior.

member functions that do not mutate the class should be marked const.

Pretty simole, isBalanced() should be marked const.

Use const references when not taking posession of the data.

For example:

bool isBalanced(const std::basic_string&lt;T&gt;&amp; expression)

This avoids extra copies.