Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Compile errors with moc and an (unused) header with variadic templates
Forum Updated to NodeBB v4.3 + New Features

Compile errors with moc and an (unused) header with variadic templates

Scheduled Pinned Locked Moved Solved General and Desktop
mocmoc.exevariadic templa
11 Posts 3 Posters 3.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by A Former User
    #2

    Hi! Did I understand this correctly that you have a template class that inherits from QObject?

    RobinDegenR 1 Reply Last reply
    0
    • ? A Former User

      Hi! Did I understand this correctly that you have a template class that inherits from QObject?

      RobinDegenR Offline
      RobinDegenR Offline
      RobinDegen
      wrote on last edited by
      #3

      @Wieland Nope, the class isn't even used (yet). Just included. It's used in other places in the codebase without problems.

      ? 1 Reply Last reply
      0
      • RobinDegenR RobinDegen

        @Wieland Nope, the class isn't even used (yet). Just included. It's used in other places in the codebase without problems.

        ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #4

        Can you show us that header?

        RobinDegenR 1 Reply Last reply
        0
        • ? A Former User

          Can you show us that header?

          RobinDegenR Offline
          RobinDegenR Offline
          RobinDegen
          wrote on last edited by
          #5

          @Wieland Sure. This class is covered by unit tests and also used in other places in the code, so it should be fine. It's just as soon as I merely include it in something that has a Q_OBJECT it fails.

          #pragma once
          
          namespace aeon
          {
          namespace utility
          {
          
          template<class... Args>
          using signal_func = std::function<void(Args...)>;
          
          template<class... Args>
          class signal_connection
          {
          public:
              signal_connection()
                  : handle_(0)
              {
              }
          
              explicit signal_connection(int handle, signal_func<Args...> func)
                  : handle_(handle)
                  , func_(func)
              {
              }
          
              int get_handle() const
              {
                  return handle_;
              }
          
              void emit(Args...args)
              {
                  func_(args...);
              }
          
          private:
              int handle_;
              signal_func<Args...> func_;
          };
          
          template<class... Args>
          class signal
          {
          public:
              signal() = default;
              ~signal() = default;
          
              signal_connection<Args...> operator+=(signal_func<Args...> f)
              {
                  return connect(f);
              }
          
              signal_connection<Args...> connect(signal_func<Args...> f)
              {
                  auto connection = signal_connection<Args...>(++last_handle_, f);
                  connections_.push_back(connection);
                  return connection;
              }
          
              void disconnect(signal_connection<Args...> c)
              {
                  connections_.remove_if([&c](const signal_connection<Args...> &other) { return other.get_handle() == c.get_handle(); });
              }
          
              void operator()(Args...args)
              {
                  for (auto c : connections_)
                  {
                      c.emit(args...);
                  }
              }
          
          private:
              int last_handle_ = 0;
              std::list<signal_connection<Args...>> connections_;
          };
          
          template<class... Args>
          class signal_mt
          {
              using mutex_type = std::mutex;
              using handle_type = std::atomic<int>;
              using list_type = std::list<signal_connection<Args...>>;
          public:
              signal_mt() = default;
              ~signal_mt()
              {
                  /* \note This does not solve the 'destruction' while signal is executing problem.
                   * Reasoning:
                   * Thread a is the owner (he creates and destroys) and thread b executes the signal multiple times. Then
                   * while the signal is being destroyed from thread a, thread b tries to execute the signal. Thread a will
                   * acquire the mutex and execute the signal destructor. When the signal is destroyed it will release the
                   * mutex and allow thread b to execute the signal that does not exist. Which will result in havoc.
                   */
                  std::lock_guard<mutex_type> guard(lock_);
                  connections_.clear();
              }
          
              signal_connection<Args...> operator+=(signal_func<Args...> f)
              {
                  return connect(f);
              }
          
              signal_connection<Args...> connect(signal_func<Args...> f)
              {
                  auto connection = signal_connection<Args...>(++last_handle_, f);
                  {
                      std::lock_guard<mutex_type> guard(lock_);
                      connections_.emplace_back(connection);
                  }
          
                  return connection;
              }
          
              void disconnect(signal_connection<Args...> c)
              {
                  std::lock_guard<mutex_type> guard(lock_);
                  connections_.remove_if([&c](const signal_connection<Args...> &other) { return other.get_handle() == c.get_handle(); });
              }
          
              void operator()(Args...args)
              {
                  std::lock_guard<mutex_type> guard(lock_);
                  for (auto &c : connections_)
                      c.emit(args...);
              }
          
          private:
              handle_type last_handle_{ 0 };
              list_type connections_;
              mutex_type lock_;
          };
          
          } // namespace utility
          } // namespace aeon
          
          1 Reply Last reply
          0
          • ? Offline
            ? Offline
            A Former User
            wrote on last edited by A Former User
            #6

            That's the problem:

            void emit(Args...args)
            {
            func_(args...);
            }

            You can't have a function named "emit" because that's a special keyword for the MOC. Simply rename it to something else.

            1 Reply Last reply
            1
            • RobinDegenR Offline
              RobinDegenR Offline
              RobinDegen
              wrote on last edited by
              #7

              Ah! Hmm.. I'd have to see if I can get away with renaming it. But if this works it'd be a great help thanks. I'll come back to you to let you know if that worked.

              1 Reply Last reply
              0
              • RobinDegenR Offline
                RobinDegenR Offline
                RobinDegen
                wrote on last edited by RobinDegen
                #8

                Great that has indeed worked.

                ? 1 Reply Last reply
                0
                • RobinDegenR RobinDegen

                  Great that has indeed worked.

                  ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #9

                  @RobinDegen Great :)

                  1 Reply Last reply
                  1
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #10

                    Yes. It's a macro that expands to nothing. There are couple more of these: signals and slots. If they cause trouble you can disable them and use even uglier (but not clashing) macros like Q_EMIT.

                    RobinDegenR 1 Reply Last reply
                    1
                    • Chris KawaC Chris Kawa

                      Yes. It's a macro that expands to nothing. There are couple more of these: signals and slots. If they cause trouble you can disable them and use even uglier (but not clashing) macros like Q_EMIT.

                      RobinDegenR Offline
                      RobinDegenR Offline
                      RobinDegen
                      wrote on last edited by
                      #11

                      @Chris-Kawa Oh thanks for that. That might actually be a much better solution for us.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved