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.0k 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.
  • RobinDegenR Offline
    RobinDegenR Offline
    RobinDegen
    wrote on 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 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