To do this accurately, you need a full C++ parser and name resolver because you need not only the function declarations but also the context that makes them well defined. For instance, if you have a declaration
void foo<T>(...){ ... }
in the file, and there's a type T in the file, you better retain the declaration for T, and whatever declarations are used to define T, etc. So you have keep the web of
definitions supporting foo... and you have to decide if you want to keep those that come from include files or not.
Our DMS Software Reengineering Toolkit is customizable general purpose program analysis and transformation machinery. With its C++ Front End, one can parse C++ code (including #includes), build Abstract Syntax Trees (ASTs), resolve names and types out of the box. Customization code would then determine the web of references necessary, and for each reference, convert it into a signature (instead of an implementation) if necessary, by applying source-to-source program transformations to the ASTs. DMS's prettyprinter could then produce the final output text.
DMS has been used for large scale C++ (re)engineering on other big projects.
Of course, you can always write some bad hack to simulate this, if you don't mind an answer you are likely to have to patch by hand.