2015-12-03 135 views
1

我有一個成員函數,它從同一個類的串口和少量解析器函數接收一些數據,然後將接收到的數據解析爲特定格式。所有的解析函數都採用相同的參數。我想要的是通過任何類型的解析器函數來接收函數,使接收函數返回與解析器返回相同的類型。 什我曾嘗試:模板函數採用任何函數並返回函子的類型返回

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)' 

用下面的模板參數: 「F = QHash(__thiscall富:: LocalConnector :: *)(的QByteArray )」

+0

如果你的編譯器支持C++ 14,你可以省略'decltype(...)'回報完全的類型,讓編譯器推斷返回類型。 – Jens

+0

@Jens注意到它不會再是SFINAE了(但在這種情況下它可能不是問題) –

+0

@PiotrSkotnicki對,但我認爲OP不希望有任何SFINAE,他只是想要一個函數返回與解析器函數相同的類型,無論它是什麼。 – Jens

回答

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>())) 
+0

非常感謝! –