2014-09-27 19 views
0

我試圖將我的OpenGL應用程序中的一個移植到使用NDK的Android,並且遇到了一個奇怪的編譯錯誤,弄清楚!「沒有匹配的函數調用'綁定'」當使用Android NDK編譯時

我有以下的模板功能,以幫助檢測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函數的一部分。

任何人都可以看到問題在哪裏?

編輯:剛纔看到調用綁定是完全沒有意義的,我可以直接調用傳遞函數。即使如此,我很好奇,想知道發生了什麼導致它終將以失敗告終:)

回答

0

也許它是由C++標準版,編譯時您可以嘗試添加-std = C++ 11 -stdlib =的libC++引起編譯器參數

+0

呀,試過了:(我得到它的工作雖然通過移除bind()的調用,也想知道爲什麼,雖然 – Kazade 2014-09-27 09:40:11

1

我編譯了您提供的代碼與clang-3.5和g ++ 4.8.2沒有erorrs。

#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 
+0

。當然,這與Android有關,儘管Android NDK只有3.3版本,所以它可能是... – Kazade 2014-09-27 10:26:04