C++ 获取任何函子并返回函子返回类型的模板函数

C++ 获取任何函子并返回函子返回类型的模板函数,c++,c++11,templates,stdbind,C++,C++11,Templates,Stdbind,我有一个成员函数,它从串口接收一些数据,在同一个类中有几个解析器函数,然后将接收到的数据解析为特定的格式。所有解析函数都采用相同的参数。我想要的是将任何类型的解析器函数传递给receive函数,使receive函数返回与解析器返回相同的类型。 我试过什么: class Foo { public: template<typename F> auto receive(F parser) -> decltype(parser(std::declval(QByteArr

我有一个成员函数,它从串口接收一些数据,在同一个类中有几个解析器函数,然后将接收到的数据解析为特定的格式。所有解析函数都采用相同的参数。我想要的是将任何类型的解析器函数传递给receive函数,使receive函数返回与解析器返回相同的类型。 我试过什么:

class Foo
{
public:
    template<typename F>
    auto receive(F parser) -> decltype(parser(std::declval(QByteArray)))
    {
        QByteArray response = readAll();
        return parser(response);
    }

    QHash<QString, QVariant> parseHash(QByteArray data);
    QString parseString(QByteArray data);
    void doStuff();
};

void Foo::doStuff()
{
    QHash<QString, QVariant> response = receive(&Foo::parseHash);    // Compilation error

    // Another try..
    response = receive(std::bind(&Foo::parseHash, this, std::placeholders::_1)); // Also compilation error
}
使用以下模板参数: “F=QHash(uu thiscall Foo::LocalConnector::*)(QByteArray)

在下面的代码段中:

QHash<QString, QVariant> response = receive(&Foo::parseHash);
或者简单地使
parseHash
成为一个静态成员函数

此外,您的表达SFINAE中有一个拼写错误,应该是:

decltype(parser(std::declval<QByteArray>()))
decltype(解析器(std::declval())

如果你的编译器支持C++14,你可以完全省略
decltype(…)
返回类型,让编译器推断返回类型。@Jens注意,这样它就不能再使用SFINAE了(但在这种情况下这可能不是问题)@PiotrSkotnicki是的,但我认为OP这里不需要任何SFINAE,他只想要一个返回与解析器函数相同类型的函数,不管它是什么。
void Foo::doStuff()
{
    auto callback = std::bind(&Foo::parseHash, this, std::placeholders::_1);

    QHash<QString, QVariant> response = receive(callback);
}
decltype(parser(std::declval<QByteArray>()))