【发布时间】:2013-05-28 14:28:13
【问题描述】:
我有以下充当代理的模板类。它有一个名为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&)。这正是我希望看到的签名。
第一行的 Clang 错误:
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 引用来编译它?
【问题讨论】:
标签: c++ templates type-deduction