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
QtWS25 Last Chance

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.0k Views
  • 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.
  • R Offline
    R Offline
    RobinDegen
    wrote on 29 May 2016, 17:34 last edited by RobinDegen
    #1

    I have some c++14 code in my project using variadic templates. This code works perfectly on Visual Studio 2015, gcc 6 (linux) and clang (osx 10.11.5). These classes are even 100% covered in my unittests.

    I recently introduced Qt 5 into the codebase. When this header containing the class with variadic templates is even included in a cpp file that had it's header file moc'ed (through qt5_wrap_cpp in cmake), it spits out loads of errors:

    [ 68%] Building CXX object engine/CMakeFiles/aeon_engine.dir/platform/qt/platform_qt_opengl_widget.cpp.o
    In file included from /Users/robindegen/Development/Projects/aeon/engine/platform/qt/platform_qt_opengl_widget.cpp:17:
    In file included from /Users/robindegen/Development/Projects/aeon/engine/platform/qt/platform_qt_window.h:17:
    In file included from /Users/robindegen/Development/Projects/aeon/engine/platform/platform_window.h:17:
    In file included from /Users/robindegen/Development/Projects/aeon/engine/gfx/gfx_render_target.h:18:
    In file included from /Users/robindegen/Development/Projects/aeon/dep/libaeon/src/aeon/utility.h:63:
    /Users/robindegen/Development/Projects/aeon/dep/libaeon/src/aeon/utility/signals.h:46:19: error: expected ')'
        void emit(Args...args)
                      ^
    /Users/robindegen/Development/Projects/aeon/dep/libaeon/src/aeon/utility/signals.h:46:14: note: to match this '('
        void emit(Args...args)
                 ^
    /Users/robindegen/Development/Projects/aeon/dep/libaeon/src/aeon/utility/signals.h:46:15: error: declaration of 'Args'
          shadows template parameter
        void emit(Args...args)
                  ^
    /Users/robindegen/Development/Projects/aeon/dep/libaeon/src/aeon/utility/signals.h:26:19: note: template parameter is
          declared here
    template<class... Args>
                      ^
    /Users/robindegen/Development/Projects/aeon/dep/libaeon/src/aeon/utility/signals.h:46:15: error: field has incomplete
          type 'void'
        void emit(Args...args)
    

    Any idea's on how to fix this? Currently i'm not even using this class, and it's already giving problems. When I comment out the inclusion if this header, it works perfectly.; I want to start using this class in the future though, so just not including this header isn't an option. Anybody any ideas?

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on 29 May 2016, 17:54 last edited by A Former User
      #2

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

      R 1 Reply Last reply 29 May 2016, 18:02
      0
      • ? A Former User
        29 May 2016, 17:54

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

        R Offline
        R Offline
        RobinDegen
        wrote on 29 May 2016, 18:02 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 29 May 2016, 18:05
        0
        • R RobinDegen
          29 May 2016, 18:02

          @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 29 May 2016, 18:05 last edited by
          #4

          Can you show us that header?

          R 1 Reply Last reply 29 May 2016, 18:16
          0
          • ? A Former User
            29 May 2016, 18:05

            Can you show us that header?

            R Offline
            R Offline
            RobinDegen
            wrote on 29 May 2016, 18:16 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 29 May 2016, 18:21 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
              • R Offline
                R Offline
                RobinDegen
                wrote on 29 May 2016, 18:29 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
                • R Offline
                  R Offline
                  RobinDegen
                  wrote on 29 May 2016, 18:43 last edited by RobinDegen
                  #8

                  Great that has indeed worked.

                  ? 1 Reply Last reply 29 May 2016, 18:45
                  0
                  • R RobinDegen
                    29 May 2016, 18:43

                    Great that has indeed worked.

                    ? Offline
                    ? Offline
                    A Former User
                    wrote on 29 May 2016, 18:45 last edited by
                    #9

                    @RobinDegen Great :)

                    1 Reply Last reply
                    1
                    • Chris KawaC Online
                      Chris KawaC Online
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on 29 May 2016, 18:46 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.

                      R 1 Reply Last reply 29 May 2016, 18:50
                      1
                      • Chris KawaC Chris Kawa
                        29 May 2016, 18:46

                        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.

                        R Offline
                        R Offline
                        RobinDegen
                        wrote on 29 May 2016, 18:50 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

                        4/11

                        29 May 2016, 18:05

                        topic:navigator.unread, 7
                        • Login

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