0

I have an abstract class which defines the basic functionality of a submodule for my application. Let's call this abstract class IProdBridge.

IProdBridge contains virtual and non-virtual methods and also some pure-virtual methods.

Because this software runs on a multitude of different platforms, the base class handles most of the functionality, while its specialisations handle the platform-specific functionality (e.g. handling of endianness on certain platforms).

Let's call the specialised class TgurProdBridge.

Simply deriving from the base class IProdBridge works just fine, however I want to mark the specialised class as final, so it may not be overridden in the future.

Maybe I'm just having a massive brain fart right now, but this is what my specialised class definition looks like:

class TgurProdBridge final: public IProdBridge {
                                           // ^ error: expected class-name before ‘{’ token
        public: // +++ Static +++
            static TgurProdBridge& getInstance(milliseconds loopInterval = milliseconds(-1), ProdResponseCallback callback = {},
                                             json settings = "{}"_json, LogLevel logLevel = LOGLEVEL_MAXVALUE, string logPath = "") {
                static TgurProdBridge* instance = nullptr;

                if (instance == nullptr) {
                    if (loopInterval == DEFAULT_MS || !callback || settings.empty() || logLevel == LOGLEVEL_MAXVALUE || logPath.size() == 0) {
                        throw getSysError(0xbada79, "Invalid arguments passed for object instantiation! Did you set all the arguments?");
                    }

                    instance = new TgurProdBridge(loopInterval, callback, settings, logLevel, logPath);
                }

                return instance;
            }

        public: // +++ Destructor +++
            ~TgurProdBridge() {  }

        private: // +++ Constructor / Destructor +++
            TgurProdBridge(milliseconds loopInterval, ProdResponseDataCallback callback, json settings, LogLevel logLevel, string logPath):
            IProdBridge(loopInterval, callback, settings) {
                getLoggerInstance() = new ConsoleLogger(__FUNCTION__, logLevel, true, 0, true, true, logPath, 128);
                getLoggerInstance()->setCurrentApplicationName(__FUNCTION__);
                getLoggerInstance()->setCurrentLoggerFormat(
                    "[[    \033[1;34m%s\033[0m   ]] [%s] [%s] %s",
                    ILogger::LOG_FMT_APPNAME.c_str(), 
                    ILogger::LOG_FMT_DATETIME.c_str(),
                    ILogger::LOG_FMT_LOGLVL.c_str(),
                    ILogger::LOG_FMT_MSG.c_str()
                );
            }

        private: // +++ Const Static (Defaults) +++
    };

For some reason my compiler (g++ 6) is throwing the following error:

error: expected class-name before ‘{’ token
     class TgurProdBridge final: public IProdBridge {
                                                    ^

I'm compiling with C++ 14 support.

Why am I getting this issue? I should be able to mark a specialised class as final; otherwise the final keyword wouldn't make any sense.

SimonC
  • 1,547
  • 1
  • 19
  • 43
  • 1
    Are you saying that removing `final` eliminates the error? – quamrana Mar 24 '21 at 11:21
  • Yes, removing final eliminated the error. – SimonC Mar 24 '21 at 11:22
  • The error sounds like gcc is having trouble with `IProdBridge`. – quamrana Mar 24 '21 at 11:27
  • Does this answer your question? [error: expected class-name before ‘{’ token](https://stackoverflow.com/questions/5319906/error-expected-class-name-before-token) – quamrana Mar 24 '21 at 11:29
  • @quamrana I've found the error and posted my answer. I honestly don't know why removing `final` changed the behaviour though, but it's a relatively old compiler, so I might have just been unfortunate enough to run in to some bug or something like that. – SimonC Mar 24 '21 at 11:31
  • You could make a [mre] in the question if you'd like to get a proper answer. – Ted Lyngmo Mar 24 '21 at 11:46
  • The code was a minimal, reproducible example. That's all the code I had, and I'm not at liberty to disclose more than I have to. – SimonC Mar 24 '21 at 12:19
  • 1
    @SimonC I mean an example that _we_ could use to reproduce the error. As your answer shows, you have `namespace`s involved that are not shown in the question. The question also includes a lot that is not necessary to reproduce the error - but not everything needed to reproduce the error (for us). – Ted Lyngmo Mar 24 '21 at 13:26

1 Answers1

0

I've found the error

This is probably one of the worst cases of PEBKAC, but maybe this will save someone else from searching as long as I have.

I'm not entirely sure why this didn't cause a plethora of other compiler errors, but the issue was with my namespace.

This class is nested within two namespaces:

namespace MyApp { namespace ProdBridge {

    class ...

} /* namespace ProdBridge */ } /* namespace MyApp */

However, instead of that my namespaces looked like this:

namespace { namespace ProdBridge {

    class ...

} /* namespace ProdBridge */ } /* namespace MyApp */

Why removing the final keyword "fixed" this error is beyond me. Sorry for the waste of your time

SimonC
  • 1,547
  • 1
  • 19
  • 43