模板函数采用任何仿函数并返回仿函数返回的类型

时间:2015-12-03 07:02:56

标签: c++ c++11 stdbind

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

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
}

在这两种情况下,编译都会失败并显示消息

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

使用以下模板参数: &#39; F = QHash(__thiscall Foo :: LocalConnector :: *)(QByteArray)&#39;

1 个答案:

答案 0 :(得分:1)

在下面的代码段中:

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

parseHash是一个非静态成员函数,因此它需要一个隐式对象参数。否则,表达式SFINAE失败,使receive成为不可行的候选者。

以下内容应该起作用:

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

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

或者简单地使parseHash成为静态成员函数。

另外,你的表达SFINAE中有一个拼写错误,它应该是:

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