N
N
Nikita Derbenev2020-09-01 21:44:46
Android
Nikita Derbenev, 2020-09-01 21:44:46

Android NDK Error: no matching member function for call to 'push_back'?

There was a problem while porting my game to android. The Android NDK compiler complains about this line:

if(b==13) rock.push_back({(uint16_t)(x*64),(uint16_t)(y*64),0,0});

Compiler output:
spoiler
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:externalNativeBuildDebug'.
> Build command failed.
  Error while executing process /Android/NDK/ndk-build with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/media/files/Android/project/app/jni/Android.mk NDK_APPLICATION_MK=/media/files/Android/project/app/jni/Application.mk APP_ABI=mips NDK_ALL_ABIS=mips NDK_DEBUG=1 APP_PLATFORM=android-14 NDK_OUT=/media/files/Android/project/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=/media/files/Android/project/app/build/intermediates/ndkBuild/debug/lib APP_PLATFORM=android-14 /media/files/Android/project/app/build/intermediates/ndkBuild/debug/obj/local/mips/libmain.so}
  /media/files/Android/NDK/build/core/setup-app.mk:81: Android NDK: Application targets deprecated ABI(s): mips    
  /media/files/Android/NDK/build/core/setup-app.mk:82: Android NDK: Support for these ABIs will be removed in a future NDK release.    
  Android NDK: WARNING: Unsupported source file extensions in /media/files/Android/project/app/jni/src/Android.mk for module main    
  Android NDK:   FC/SDL_FontCache.h    
  [mips] Compile++      : main <= main.cpp
  In file included from /media/files/Android/project/app/jni/src/main.cpp:1:
  In file included from /media/files/Android/project/app/jni/src/include.h:113:
  /media/files/Android/project/app/jni/src/game.cpp:45:39: error: no matching member function for call to 'push_back'
              if(b==13)            rock.push_back({(uint16_t)(x*64),(uint16_t)(y*64),0,0});
                                   ~~~~~^~~~~~~~~
  /media/files/Android/NDK/sources/cxx-stl/llvm-libc++/include/vector:677:36: note: candidate function not viable: cannot convert initializer list argument to 'const std::__ndk1::__vector_base<rck, std::__ndk1::allocator<rck> >::value_type' (aka 'const rck')
      _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
                                     ^
  /media/files/Android/NDK/sources/cxx-stl/llvm-libc++/include/vector:680:36: note: candidate function not viable: cannot convert initializer list argument to 'std::__ndk1::vector<rck, std::__ndk1::allocator<rck> >::value_type' (aka 'rck')
      _LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
                                     ^

rc class:
class rck{
public:
    unsigned short x,y;
    void show();
    int tm=0;
    uint8_t type=0;
};
//////////////////////
std::vector<rck> rock;

BUT! g++ compiles this code fine, but the Android NDK throws an error. Why is this happening and how to fix this error?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Evgeny Shatunov, 2020-09-01
@Nikita_yfh

class rck{
public:
    unsigned short x,y;
    void show();
    int tm=0;
    uint8_t type=0;
};

Free commenting on code state
Тут у нас большие проблемы с читаемостью кода. stdint соседствует с сырыми конструкциями модификации типа, методы вперемешку с полями, класс вместо структуры, использование запятой при объявлении полей, имена в одну букву и акронимы. Неинициализированные поля - распространенный источник ошибок.
Лучше будет с молоду учиться правильно оформлять свой код. Например так.
struct rck final
{
  uint16_t x = 0;
  uint16_t y = 0;
  int32_t tm = 0;
  uint8_t type = 0;
  
  
  void show();
};

Не берусь менять имена, т.к. не понимаю их семантики. Каждое имя должно отражать семантику своего существования или должно быть стерто из кода.

You seem to have declared an aggregate type with an implicit default constructor, in which only the and fields are tminitialized type.
rock.push_back({(uint16_t)(x*64),(uint16_t)(y*64),0,0});

Here, before calling to push_back, a fictitious one is formed std::initializer_list<uint16_t>with two elements inside.
In a general sense, two more arguments must be specified before the full list of arguments. Then this entry can be considered an aggregate initialization of a temporary object of type rck.
This form of aggregate initialization is standardized in C++11. Prior to C++14, aggregate initialization was disabled for types that have fields initialized at the place of declaration (in the code, these are fields tmand type). Each following standard of the requirement to aggregate initialization only toughens.
GCC has long been notorious for its poor support for the language standard. This means that if the code passes the g++ translation, it is far from the fact that it conforms to the standard.
NDK today for builduses clang, which is currently considered as close to the standard compiler as possible.
All this should make it clear that this code does not comply with the language standard and should not be compiled. No suitable two-argument constructor rckis defined for the type, and the type is not an aggregate.
That g++ was able to build this code will remain on the conscience of g++.
Another important point will be the exact understanding of which language standard is chosen for translating your code.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question