The following test code compiles and executes correctly:

class RegExpTest : public Framework
{
   template <class T> int reParseNumbers( std::string, std::set<T>&, double=-1 )
            throw(Exception );
}

template <class T> int RegExpTest::reParseNumbers( std::string s, std::set<T> & numSet, double set_size_limit )
      throw( Exception )
{
  // do some regular expression stuff and return an int 
}

However when I attempt to incorporate this as a standalone inline function in a namespace (and not as part of a class):

namespace StringFunctions
{

template <class T>
      inline int reParseNumbers(   std::string s, 
                                    std::set<T> & numSet, 
                                    const double set_size_limit=-1 )
      throw( StringException );

template <class T> 
      inline int reParseNumbers(   std::string s, 
                                    std::set<T>& numSet, 
                                    const double set_size_limit )
      throw( StringException )
      {
       // do some regular expression stuff and return an int 
      }
}

I get the following error messages:

"StringFunctions.hpp", line 5: Error: Templates can only declare classes or functions.
"StringFunctions.hpp", line 11: Error: Templates can only declare classes or functions.

I've narrowed the problem with the second code example down to the std::set<T> parameter that is being passed. Although the code compiles fine in as part of a class, when it is included as a standalone inline function in a namespace, the compiler chokes on the second std::set<T> parameter with the error message above.

What should I do differently to inline a templated method standalone in a namespace (as opposed to having it as part of a class)?

Any advice would be much appreciated

Dani AI

Generated

The code you posted is valid C++ when the template appears at namespace scope, so the compiler message "Templates can only declare classes or functions" means the compiler is seeing the template in a context where templates are not allowed (not that std::set<T> is inherently broken). Common, practical causes and a short debug checklist:

  • The header ended up being included inside a function or inside a class body. A template-declaration must be at namespace scope or at class scope; if you accidentally #include "StringFunctions.hpp" from inside a function, the compiler will emit that exact error.
  • Preprocessor macro collision or stray token above the template. Search for #define set or any macro named StringFunctions and check for a missing ; or other syntax error earlier in the header that could confuse the parser. Use the preprocessor output (g++ -E source.cpp > preprocessed.cpp) to see what the compiler actually sees.
  • Missing/misordered includes or weird exception-spec parsing. Make sure <set> and <string> are included before the template and, as a quick test, try removing the dynamic exception specification (throw(...)) — older compilers/parsers sometimes choke there. Also ensure the default argument appears only in the first declaration (if you keep a separate forward declaration).

Two practical fixes that eliminate the common pitfalls:

  • Put the full template definition directly in the header inside the named namespace (preferred for templates). That avoids forward-declaration/definition ordering issues and is the usual pattern for function templates.
  • If you need a separate declaration, keep both declaration and definition at namespace scope in the same header; the inline keyword does not forbid having a prior declaration — ’s suggestion that “inline OR the declaration” is incorrect.

Troubleshooting tips: try a tiny standalone file containing only a minimal namespace + one template function to confirm the compiler accepts the pattern; if it does, the problem is elsewhere in your project (include locations or macros). If the small test also fails, try a different compiler/version to rule out a compiler bug or old-parser quirk.

The problem is that you can have the inline OR the declaration.
You can't have both. So if you delete 5,6,7,8 all isl be fine.
If you wish to define the function outside of the namespace definition then delete lines 10-17.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.