【问题标题】:"no matching function call to 'bind'" when compiling using the Android NDK使用 Android NDK 编译时“没有匹配的函数调用到‘bind’”
【发布时间】:2014-09-27 09:09:26
【问题描述】:

我正在尝试使用 NDK 将我的一个 OpenGL 应用程序移植到 Android,但我遇到了一个我无法弄清楚的奇怪编译错误!

我有以下模板函数来帮助检测 OpenGL 错误:

template<typename Res, typename Func, typename... Args>
struct Checker {
    static Res run(Func&& func, Args&&... args) {
        Res result = std::bind(std::forward<Func>(func), std::forward<Args>(args)...)();
        check_and_log_error("", 0);
        return result;
    }
};

template<typename Func, typename... Args>
struct Checker<void, Func, Args...> {
    static void run(Func&& func, Args&&... args) {
        std::bind(std::forward<Func>(func), std::forward<Args>(args)...)();
        check_and_log_error("", 0);
    }
};

template<typename Func>
struct Checker<void, Func> {
    static void run(Func&& func) {
        func();
        check_and_log_error("", 0);
    }
};

}

template<typename Res=void, typename Func, typename... Args>
Res GLCheck(Func&& func, Args&&... args) {
    GLThreadCheck::check();
    return GLChecker::Checker<Res, Func, Args...>::run(std::forward<Func>(func), std::forward<Args>(args)...);
}

然后我可以像这样调用 OpenGL 函数:

GLCheck(glBindTexture, GL_TEXTURE_2D, gl_tex_);

如果调用因某种原因失败,应用程序将记录错误。这一切在桌面上都可以正常工作,但是当我尝试为 Android 编译时,每个 OpenGL 调用都会产生如下编译错误:

kglt/kglt/utils/gl_error.h:30:9: error: no matching function for call to 'bind'
        std::bind(std::forward<Func>(func), std::forward<Args>(args)...)();
        ^~~~~~~~~
kglt/kglt/utils/gl_error.h:48:52: note: in instantiation of member function 'GLChecker::Checker<void, void (&)(unsigned int, unsigned int) __attribute__((pcs("aapcs"))), int, unsigned int &>::run' requested here
    return GLChecker::Checker<Res, Func, Args...>::run(std::forward<Func>(func), std::forward<Args>(args)...);
                                                   ^
kglt/kglt/texture.cpp:77:5: note: in instantiation of function template specialization 'GLCheck<void, void (&)(unsigned int, unsigned int) __attribute__((pcs("aapcs"))), int, unsigned int &>' requested here
    GLCheck(glBindTexture, GL_TEXTURE_2D, gl_tex_);
    ^
/home/kazade/Android/android-ndk-r10/sources/cxx-stl/gnu-libstdc++/4.8/include/functional:1682:5: note: candidate template ignored: couldn't infer template argument '_Result'
    bind(_Func&& __f, _BoundArgs&&... __args)
    ^
/home/kazade/Android/android-ndk-r10/sources/cxx-stl/gnu-libstdc++/4.8/include/functional:1655:5: note: candidate template ignored: substitution failure [with _Func = void (&)(unsigned int, unsigned int) __attribute__((pcs("aapcs"))),
      _BoundArgs = <int, unsigned int &>]
    bind(_Func&& __f, _BoundArgs&&... __args)

我不明白为什么模板推导失败了,尤其是上面的“替代失败”似乎显示了兼容的参数被传递下来。我能看到的唯一奇怪的是__attribute__((pcs("aapcs"))),它是 OpenGL 函数的一部分。

谁能看出问题出在哪里?

编辑:刚刚看到对 bind 的调用完全没有意义,我可以直接调用传递的函数。尽管如此,我还是很想知道是什么导致它失败:)

【问题讨论】:

    标签: c++ templates opengl-es android-ndk


    【解决方案1】:

    我用 clang-3.5 和 g++ 4.8.2 编译了你提供的代码,没有错误。

    #include <utility>
    #include <functional>
    
    #include <GL/gl.h>
    
    namespace GLChecker {
    template <typename Res, typename Func, typename... Args>
    struct Checker {
      static Res run(Func&& func, Args&&... args) {
        Res result
            = std::bind(std::forward<Func>(func), std::forward<Args>(args)...)();
        // check_and_log_error("", 0);
        return result;
      }
    };
    
    template <typename Func, typename... Args>
    struct Checker<void, Func, Args...> {
      static void run(Func&& func, Args&&... args) {
        std::bind(std::forward<Func>(func), std::forward<Args>(args)...)();
        // check_and_log_error("", 0);
      }
    };
    
    template <typename Func>
    struct Checker<void, Func> {
      static void run(Func&& func) {
        func();
        // check_and_log_error("", 0);
      }
    };
    }
    
    template <typename Res = void, typename Func, typename... Args>
    Res GLCheck(Func&& func, Args&&... args) {
      // GLThreadCheck::check();
      return GLChecker::Checker<Res, Func, Args...>::run(
          std::forward<Func>(func), std::forward<Args>(args)...);
    }
    
    int main() {
      int gl_tex_ = 0;
      GLCheck(glBindTexture, GL_TEXTURE_2D, gl_tex_);
    
      return 0;
    }
    

    命令行:

    g++ -std=c++11  ~/Desktop/main.cpp -lGL
    

    clang++ -std=c++11  ~/Desktop/main.cpp -lGL
    

    【讨论】:

    • 那么肯定和Android有关,虽然Android NDK只有clang 3.3,所以可能是...
    【解决方案2】:

    可能是c++标准版本造成的,编译时可以尝试在编译器参数中加入-std=c++11 -stdlib=libc++

    【讨论】:

    • 是的,试过了 :( 我通过删除 bind() 调用让它工作了,但希望我知道为什么。
    猜你喜欢
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    相关资源
    最近更新 更多