简体   繁体   中英

Template function taking any functor and returning the type of the functor return

I have an member function, which receives some data from serial port and few parser functions in the same class, which then parse recieved data to specific format. All the parse functions take same parameter. What I want is to pass any kind of parser function to recieve function an to make recieve function return same type as parser returns. Wha I have tried:

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
}

In both cases compilation fails with message

error: C2893: Failed to specialize function template 'unknown-type Foo::receive(F)'

With the following template arguments: 'F=QHash (__thiscall Foo::LocalConnector::* )(QByteArray)'

In the below snippet:

QHash<QString, QVariant> response = receive(&Foo::parseHash);

parseHash is a non-static member function, hence it requires an implicit object parameter. Otherwise, the expression SFINAE fails, making receive a non-viable candidate.

The following should work instead:

void Foo::doStuff()
{
    auto callback = std::bind(&Foo::parseHash, this, std::placeholders::_1);

    QHash<QString, QVariant> response = receive(callback);
}

Or simply make parseHash a static member function.

Also, there's a typo in your expression SFINAE, it should be:

decltype(parser(std::declval<QByteArray>()))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM