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

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.4k 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 Online
                    Chris KawaC Online
                    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