我有以下模板類充當代理。它有一個名爲call
的方法,該方法應該用於調用包裝對象上的方法。這有一個問題。類型扣除失敗,我不明白爲什麼。類型扣減失敗,並指向成員方法
Hudsucker::f
需要std::string
然後無論我通過std::string
或const
引用它編譯器能夠調用正確的方法。
但是在Hudsucker::g
的情況下需要const
參考std::string
在兩種情況下都使用GCC和Clang類型扣減失敗。
用於第一線GCC錯誤:
main.cpp:36:28: error: no matching function for call to ‘Proxy<Hudsucker>::call(void (Hudsucker::*)(const string&), const string&)’
main.cpp:36:28: note: candidate is:
main.cpp:10:10: note: template<class A> void Proxy::call(void (T::*)(A), A) [with A = A; T = Hudsucker]
main.cpp:10:10: note: template argument deduction/substitution failed:
main.cpp:36:28: note: deduced conflicting types for parameter ‘A’ (‘const std::basic_string<char>&’ and ‘std::basic_string<char>’)
尤其,該位是奇怪:no matching function for call to Proxy<Hudsucker>::call(void (Hudsucker::*)(const string&), const string&)
。這正是我期望看到工作的簽名。
鏘錯誤的第一行:
main.cpp:36:7: error: no matching member function for call to 'call'
p.call(&Hudsucker::g, s); // <- Compile error
~~^~~~
main.cpp:10:10: note: candidate template ignored: deduced conflicting types for parameter 'A' ('const std::basic_string<char> &' vs. 'std::basic_string<char>')
void call(void (T::*f)(A), A a)
代碼:
#include <string>
#include <iostream>
template <typename T> class Proxy
{
public:
Proxy(T &o): o_(o) {}
template <typename A>
void call(void (T::*f)(A), A a)
{
(o_.*f)(a);
}
private:
T &o_;
};
class Hudsucker
{
public:
void f(std::string s) {}
void g(std::string const &s) {}
};
int main()
{
Hudsucker h;
Proxy<Hudsucker> p(h);
std::string const s = "For kids, you know.";
std::string const &r = s;
p.call(&Hudsucker::f, s);
p.call(&Hudsucker::f, r);
p.call(&Hudsucker::g, s); // <- Compile error
p.call(&Hudsucker::g, r); // <- Compile error
return 0;
}
你能解釋爲什麼類型推演以這種方式失敗了呢?有沒有辦法讓這個編譯const
引用?
我在這裏不是專家通過anymeans,但你不會想在這裏用完美轉發。 –
@MikeVine:是的,這的確是合適的,但是在這個答案中,我想提供一個工作解決方案,只需要很少的修改,這樣OP就可以理解他原來的程序出了什麼問題(完美的轉發是一種改進,解決問題本身)。無論如何,我應該添加這個作爲一個說明,謝謝! –
另外我很確定你想''type'在'* = nullptr'之前# –