【问题标题】:how to write a C++ class member function wrapper?如何编写 C++ 类成员函数包装器?
【发布时间】:2018-06-29 13:23:15
【问题描述】:

我想包装一些类成员函数并围绕它们做一些准备和清理工作。

我尝试复制一些其他线程池代码,但出现一些我无法解决的错误。如何正确操作?

#include <iostream>
#include <string>
using namespace std;
class A {
public:
    void connect() {};
    void close() {};
    template<typename F, typename ... Args>
    auto wrapper(F&& f, Args&& ... args) -> typename std::result_of<F(Args...)>::type {
        using return_type = typename std::result_of<F(Args...)>::type;
        connect();
        return_type ret = f(args...);
        close();
        return ret;
    }
    bool c(int a, string b) {}
    string c(string b) {return b;}
    bool r(int a, string b) {}
};
int main() {
    A a;
    a.connect();
    a.c(1, "abc");
    a.close(); // equal to a.wrapper(a.c, 1, "abc"); but compling error, how to write it correctly?
    cout << "result of a is: " << a.wrapper(a.c, 1, "abc") ? "successful" : "fail" << endl;
    cout << "result of another a is: " << a.wrapper(a.c, "abc") << endl;
    cout << "result of r is:" << a.wrapper(a.r, 1, "abc") << endl;
}

我得到这样的错误:

main.cpp: In function ‘int main()’:
main.cpp:25:58: error: no matching function for call to ‘A::wrapper(<unresolved overloaded function type>, int, const char [4])’
     cout << "result of a is: " << a.wrapper(a.c, 1, "abc") ? "successful" : "fail" << endl;
                                                          ^
main.cpp:25:58: note: candidate is:
main.cpp:9:10: note: template<class F, class ... Args> typename std::result_of<_Functor(_ArgTypes ...)>::type A::wrapper(F&&, Args&& ...)
     auto wrapper(F&& f, Args&& ... args) -> typename std::result_of<F(Args...)>::type {
          ^
main.cpp:9:10: note:   template argument deduction/substitution failed:
main.cpp:25:58: note:   couldn't deduce template parameter ‘F’
     cout << "result of a is: " << a.wrapper(a.c, 1, "abc") ? "successful" : "fail" << endl;
                                                          ^
main.cpp:25:87: error: invalid operands of types ‘const char [5]’ and ‘<unresolved overloaded function type>’ to binary ‘operator<<’
     cout << "result of a is: " << a.wrapper(a.c, 1, "abc") ? "successful" : "fail" << endl;
                                                                                       ^
main.cpp:26:63: error: no matching function for call to ‘A::wrapper(<unresolved overloaded function type>, const char [4])’
     cout << "result of another a is: " << a.wrapper(a.c, "abc") << endl;
                                                               ^
main.cpp:26:63: note: candidate is:
main.cpp:9:10: note: template<class F, class ... Args> typename std::result_of<_Functor(_ArgTypes ...)>::type A::wrapper(F&&, Args&& ...)
     auto wrapper(F&& f, Args&& ... args) -> typename std::result_of<F(Args...)>::type {
          ^
main.cpp:9:10: note:   template argument deduction/substitution failed:
main.cpp:26:63: note:   couldn't deduce template parameter ‘F’
     cout << "result of another a is: " << a.wrapper(a.c, "abc") << endl;



                                                                   ^

【问题讨论】:

标签: c++ c++11 templates template-meta-programming


【解决方案1】:

表达式a.c 并不是真正的指向可调用成员函数的指针。 &amp;A::c 是,但是它需要一个 A 的实例才能被调用。

有两种方法可以解决这个问题:

  1. 使用std::bind。如std::bind(&amp;A::c, a)

  2. 使用lambda。如[&amp;a](int i, std::string const&amp; s) { return a.c(i, s); }

【讨论】:

  • 你能举个例子吗?我不太明白如何正确地做到这一点。虽然我可以通过 lambda 做到,但我不能聪明和干净地做到。
【解决方案2】:

后面的代码将通过编译。但是,它仍然比预期的要复杂得多。

using sig1 = bool(A::*)(int, string);
cout << "result of a is: " << (a.wrapper(bind(static_cast<sig1>(&A::c), a, _1, _2), 1, string("abc")) ? "successful" : "fail") << endl;
//cout << "result of another a is: " << a.wrapper(a.c, "abc") << endl;
//cout << "result of r" << a.wrapper(a.r, 1, "abc") << endl;

顺便说一下,clang的报错比gcc好。当您在某些模板编程方面遇到问题时,您希望得到更清晰的错误消息,仅供参考

【讨论】:

    猜你喜欢
    • 2019-10-29
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多