c++ - 模板构造函数类型推导对于 function<> 参数不起作用(没有匹配的构造函数用于初始化...)

标签 c++

我有这个示例(我想向类 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/

相关文章:

c++ - 给定以下内容, "function"是什么类型?

java - 如何为 Android ndk 准备 .cpp 文件来构建它们?

c++ - 从IT编程到机器控制编程

c++ - valgrind 提示在 c 中做了一个非常简单的 strtok

c++ - 类中的 std::vectors

c++ - 性能比较:strstr() 与 std::string::find()

c++ - (UE4)检查一个点是否在碰撞圆内

c++ - 为什么我应该/不应该使用 "new"运算符来实例化一个类,为什么?

c++ - 需要有关#include 的帮助似乎不起作用

c# - 通过 ActiveSync 在 Windows Mobile 上运行应用程序