我有这个示例(我想向类 C
添加模板重载构造函数:
#include <iostream>
#include <functional>
#include <string>
using namespace std;
class Msg {
public:
void parse(const string &s) {
x = int(s[0]);
}
int x = 0;
};
class C {
public:
C(function<void(const string &)> cb)
: cb_(cb)
{}
template<typename TMsg>
C(function<void(const TMsg &)> cb)
: C([&, cb](const string &s) {
TMsg m; m.parse(s); cb(m);
})
{}
void test() {
cb_("foo");
}
function<void(const string &)> cb_;
};
void cb1(const string &s) {
cout << "cb1: " << s << endl;
}
void cb2(const Msg &msg) {
cout << "cb2: Msg{x=" << msg.x << "}" << endl;
}
int main() {
C c1(&cb1), c2(&cb2); c1.test(); c2.test();
return 0;
}
这给出了这个编译器错误(clang++ 9.1):
test_func_arg_overload.cpp:37:17: error: no matching constructor for initialization of 'C'
C c1(&cb1), c2(&cb2); c1.test(); c2.test();
^ ~~~~
test_func_arg_overload.cpp:12:7: note: candidate constructor (the implicit move constructor) not
viable: no known conversion from 'void (*)(const Msg &)' to 'C' for 1st argument
class C {
^
test_func_arg_overload.cpp:12:7: note: candidate constructor (the implicit copy constructor) not
viable: no known conversion from 'void (*)(const Msg &)' to 'const C' for 1st argument
class C {
^
test_func_arg_overload.cpp:14:5: note: candidate constructor not viable: no known conversion from
'void (*)(const Msg &)' to 'function<void (const std::__1::string &)>' (aka 'function<void (const
basic_string<char, char_traits<char>, allocator<char> > &)>') for 1st argument
C(function<void(const string &)> cb)
^
test_func_arg_overload.cpp:18:5: note: candidate template ignored: could not match 'function<void
(const type-parameter-0-0 &)>' against 'void (*)(const Msg &)'
C(function<void(const TMsg &)> cb)
^
1 error generated.
除了使 C
成为模板类之外,还有其他方法可以解决此问题吗?
最佳答案
您只需将函数指针转换为正确的类型即可。这应该有效:
using f_t = std::function<void(const Msg &)>;
C c2(static_cast<f_t>(&cb2));
问题是,如果没有强制转换,您将提供函数指针,该指针应自动转换为 std::function<>
如果您有确切类型的构造函数重载,就像第一个示例一样,那么这将起作用。
但在第二种情况下,重载决策与模板化版本不匹配,因为类型不匹配并且未执行类型推导。
关于c++ - 模板构造函数类型推导对于 function<> 参数不起作用(没有匹配的构造函数用于初始化...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51421290/