Matching parenthesis
Let's go top down:


charmatch is a bad name for the function. parenMatch would make much more sense.
Judging by the one range-based for loop, you're using C++11 - so might as well use it to the full extend:


You can use range-based for loops directly on a std::string. There is no need to copy it into a vector. So the input vector can be removed.
You can initialize a std::set with an initializer list:

std::set&lt;char&gt; openParen = { '(', '[', '{' };

Not sure why the range based loop variable is called i just to be copied into a loop-local variable called inputChar. You might as well name the loop variable that way.

for (auto inputChar : inputArg) {
    ....


closeParen is never used and can be removed.
exprStack is not really the best name - parenStack would be more appropriate.
You should use spaces more consistently. Your indent is off here and there and you often omit a space before the opening brace which doesn't help readability. Also a lot of people prefer 4 spaces indent but YMMV.
Use a consistent bracing style. Sometimes you put the opening brace on it's own line and sometimes it's on the previous one and sometimes the entire block is on one line.
I'd return a bool from process instead of writing directly to std::out - let the caller deal with the output concern (Single Responsibility Principle).
input in main is never used and should be removed.
You don't have to explicitly return 0 from main.




Update

Regarding your question of making charmatch more efficient: charmatch is already pretty efficient - at most 8 compares and 3 ANDs. You could turn it into a switch:

bool parenMatch(char left, char right)
{
    switch (left)
    {
        case '(': return right == ')';
        case '[': return right == ']';
        case '{': return right == '}';
    }
    return false;
}


However this is a micro-optimization which will probably have close to no effect on the execution speed, in fact I wouldn't be surprised if the generated code is almost the same.