godotengine / godot-cpp

C++ bindings for the Godot script API
MIT License
1.74k stars 575 forks source link

Compile Error with Ref<IntervalTweener> #1472

Closed Ljiong201108 closed 5 months ago

Ljiong201108 commented 6 months ago

Godot version

4.2.2 stable

godot-cpp version

4.2

System information

Ubuntu 22.04

Issue description

I tried to use Tween within a Node but during compiling, the deduction always failed.

Here is the example code of a simple _process function:

void Player::_process(double delta) {
    Ref<Tween> tween(this->create_tween());
    tween->tween_interval(1);
}

However, this could not pass the compilation. Here's the error output:

scons: Reading SConscript files ...
Building for architecture x86_64 on platform linux
scons: done reading SConscript files.
scons: Building targets ...
scons: `godot-cpp/bin/libgodot-cpp.linux.template_debug.x86_64.a' is up to date.
Compiling shared src/player.cpp ...
Compiling shared src/register_types.cpp ...
In file included from godot-cpp/gen/include/godot_cpp/classes/node.hpp:41,
                 from godot-cpp/gen/include/godot_cpp/classes/node3d.hpp:38,
                 from godot-cpp/gen/include/godot_cpp/classes/collision_object3d.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/physics_body3d.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/rigid_body3d.hpp:37,
                 from src/player.h:3,
                 from src/player.cpp:1:
godot-cpp/include/godot_cpp/classes/ref.hpp: In instantiation of 'void godot::Ref<T>::unref() [with T = godot::IntervalTweener]':
godot-cpp/include/godot_cpp/classes/ref.hpp:217:3:   required from 'godot::Ref<T>::~Ref() [with T = godot::IntervalTweener]'
src/player.cpp:46:50:   required from here
godot-cpp/include/godot_cpp/classes/ref.hpp:204:45: error: invalid use of incomplete type 'class godot::IntervalTweener'
  204 |                 if (reference && reference->unreference()) {
      |                                  ~~~~~~~~~~~^~~~~~~~~~~
In file included from src/player.cpp:9:
godot-cpp/gen/include/godot_cpp/classes/tween.hpp:48:7: note: forward declaration of 'class godot::IntervalTweener'
   48 | class IntervalTweener;
      |       ^~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/bits/move.h:57,
                 from /usr/include/c++/11/bits/stl_pair.h:59,
                 from /usr/include/c++/11/bits/stl_algobase.h:64,
                 from /usr/include/c++/11/bits/specfun.h:45,
                 from /usr/include/c++/11/cmath:1935,
                 from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/quaternion.hpp:34,
                 from godot-cpp/include/godot_cpp/variant/basis.hpp:35,
                 from godot-cpp/gen/include/godot_cpp/classes/rigid_body3d.hpp:36,
                 from src/player.h:3,
                 from src/player.cpp:1:
/usr/include/c++/11/type_traits: In instantiation of 'struct std::is_base_of<godot::Wrapped, godot::IntervalTweener>':
/usr/include/c++/11/type_traits:3257:69:   required from 'constexpr const bool std::is_base_of_v<godot::Wrapped, godot::IntervalTweener>'
godot-cpp/include/godot_cpp/core/memory.hpp:117:45:   required by substitution of 'template<class T, typename std::enable_if<is_base_of_v<godot::Wrapped, T>, bool>::type <anonymous> > void godot::memdelete(T*) [with T = godot::IntervalTweener; typename std::enable_if<is_base_of_v<godot::Wrapped, T>, bool>::type <anonymous> = <missing>]'
godot-cpp/include/godot_cpp/classes/ref.hpp:205:13:   required from 'void godot::Ref<T>::unref() [with T = godot::IntervalTweener]'
godot-cpp/include/godot_cpp/classes/ref.hpp:217:3:   required from 'godot::Ref<T>::~Ref() [with T = godot::IntervalTweener]'
src/player.cpp:46:50:   required from here
/usr/include/c++/11/type_traits:1422:38: error: invalid use of incomplete type 'class godot::IntervalTweener'
 1422 |     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
      |                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/player.cpp:9:
godot-cpp/gen/include/godot_cpp/classes/tween.hpp:48:7: note: forward declaration of 'class godot::IntervalTweener'
   48 | class IntervalTweener;
      |       ^~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/bits/move.h:57,
                 from /usr/include/c++/11/bits/stl_pair.h:59,
                 from /usr/include/c++/11/bits/stl_algobase.h:64,
                 from /usr/include/c++/11/bits/specfun.h:45,
                 from /usr/include/c++/11/cmath:1935,
                 from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/quaternion.hpp:34,
                 from godot-cpp/include/godot_cpp/variant/basis.hpp:35,
                 from godot-cpp/gen/include/godot_cpp/classes/rigid_body3d.hpp:36,
                 from src/player.h:3,
                 from src/player.cpp:1:
/usr/include/c++/11/type_traits: In instantiation of 'constexpr const bool std::is_base_of_v<godot::Wrapped, godot::IntervalTweener>':
godot-cpp/include/godot_cpp/core/memory.hpp:117:45:   required by substitution of 'template<class T, typename std::enable_if<is_base_of_v<godot::Wrapped, T>, bool>::type <anonymous> > void godot::memdelete(T*) [with T = godot::IntervalTweener; typename std::enable_if<is_base_of_v<godot::Wrapped, T>, bool>::type <anonymous> = <missing>]'
godot-cpp/include/godot_cpp/classes/ref.hpp:205:13:   required from 'void godot::Ref<T>::unref() [with T = godot::IntervalTweener]'
godot-cpp/include/godot_cpp/classes/ref.hpp:217:3:   required from 'godot::Ref<T>::~Ref() [with T = godot::IntervalTweener]'
src/player.cpp:46:50:   required from here
/usr/include/c++/11/type_traits:3257:69: error: 'value' is not a member of 'std::is_base_of<godot::Wrapped, godot::IntervalTweener>'
 3257 |   inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value;
      |                                                                     ^~~~~
In file included from godot-cpp/gen/include/godot_cpp/classes/node.hpp:41,
                 from godot-cpp/gen/include/godot_cpp/classes/node3d.hpp:38,
                 from godot-cpp/gen/include/godot_cpp/classes/collision_object3d.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/physics_body3d.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/rigid_body3d.hpp:37,
                 from src/player.h:3,
                 from src/player.cpp:1:
godot-cpp/include/godot_cpp/classes/ref.hpp: In instantiation of 'void godot::Ref<T>::unref() [with T = godot::IntervalTweener]':
godot-cpp/include/godot_cpp/classes/ref.hpp:217:3:   required from 'godot::Ref<T>::~Ref() [with T = godot::IntervalTweener]'
src/player.cpp:46:50:   required from here
godot-cpp/include/godot_cpp/classes/ref.hpp:205:34: error: no matching function for call to 'memdelete(godot::IntervalTweener*&)'
  205 |                         memdelete(reference);
      |                         ~~~~~~~~~^~~~~~~~~~~
In file included from godot-cpp/include/godot_cpp/templates/cowdata.hpp:37,
                 from godot-cpp/include/godot_cpp/variant/char_string.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/string.hpp:38,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/core/object.hpp:38,
                 from godot-cpp/gen/include/godot_cpp/classes/node.hpp:39,
                 from godot-cpp/gen/include/godot_cpp/classes/node3d.hpp:38,
                 from godot-cpp/gen/include/godot_cpp/classes/collision_object3d.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/physics_body3d.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/rigid_body3d.hpp:37,
                 from src/player.h:3,
                 from src/player.cpp:1:
godot-cpp/include/godot_cpp/core/memory.hpp:109:6: note: candidate: 'template<class T> void godot::memdelete(T*, typename std::enable_if<(! is_base_of_v<godot::Wrapped, T>)>::type*)'
  109 | void memdelete(T *p_class, typename std::enable_if<!std::is_base_of_v<godot::Wrapped, T>>::type * = nullptr) {
      |      ^~~~~~~~~
godot-cpp/include/godot_cpp/core/memory.hpp:109:6: note:   template argument deduction/substitution failed:
godot-cpp/include/godot_cpp/core/memory.hpp:118:6: note: candidate: 'template<class T, typename std::enable_if<is_base_of_v<godot::Wrapped, T>, bool>::type <anonymous> > void godot::memdelete(T*)'
  118 | void memdelete(T *p_class) {
      |      ^~~~~~~~~
godot-cpp/include/godot_cpp/core/memory.hpp:118:6: note:   substitution of deduced template arguments resulted in errors seen above
scons: *** [src/player.os] Error 1
scons: building terminated because of errors.

I'm not sure if I used it in a proper way, since I'm totally new to gdextension. I would like to ask how I fixed this problem or how I should use it. Thanks!

Steps to reproduce

Simply create a node with the _process function like this:

void Player::_process(double delta) {
    Ref<Tween> tween(this->create_tween());
    tween->tween_interval(1);
}

Then try to compile.

Minimal reproduction project

Can provide my code if necessary.

AThousandShips commented 6 months ago

You need to include the header for the type in question, it's forward declared because of circular includes otherwise

Ljiong201108 commented 5 months ago

Ah, you are right! I didn't notice that the return type is not included. Thanks for your reply!