It is possible to customize the behavior of cindent in Vim by writing a wrapper function. All you need is to find out which indentifiers Vim uses for calculating the new indent, and then find an appropriate regular expression.

Suppose we do not want to indent stuff in namespace declarations. I found out that it is enough to adjust the indentation of the first definition (except for a special case when using inheritance (“: public …“), see the code):

setlocal nolisp
setlocal noautoindent

setlocal indentexpr=GetCppIndent(v:lnum)

if exists("*GetCppIndent")
    finish
endif

function! GetCppIndent(lnum)
    let cindent = cindent(a:lnum)
    if a:lnum == 1 | return cindent | endif

    let pattern1 = 'namespaces+S+s*{s*%$'
    " pattern2 is used to match this case:
    " class c : public b
    "     { <-- cursor
    let clspat = 'classs+S+s*:s*[^{]*'
    let pattern2 = 'namespaces+S+s*{s*'.clspat.'%$'

    let lines = join(getline(max([ a:lnum - 10, 1]) , a:lnum-1), ' ')

    if  lines =~ pattern1
        return indent(CppFindOccurence('namespace', a:lnum))
    elseif  lines =~ pattern2 && getline(a:lnum) =~ '^s*{'
        return indent(CppFindOccurence('class', a:lnum))
    else
        return cindent
    endif
endfunction

function! CppFindOccurence(pattern, lnum)
    for line in range(a:lnum-1,a:lnum-10,-1)
        if getline(line) =~ a:pattern
            return line
        endif
    endfor
    return -1
endfunction

Please note that this is a hack, and thus not perfect. For instance, it does not take comments or preprocessing directives into account, but that should be easy to implement if it is an issue for you…