2016-11-17 29 views
1

我只是好奇。我傳遞指針與簽名從const&參數到&參數的轉換無效似乎是無稽之談?

void printCommandReceived(const CommandDescriptor &descriptor) 

作爲第三個參數的功能與簽名

CommandLogFilter::CommandLogFilter(QSharedPointer<LogServer> logServer, QObject *parent, 
         void (*preprocessValidCommand)(CommandDescriptor &descriptor)) 

和G獲取錯誤構造器++編譯器:

error: invalid conversion from ‘void (*)(const CommandDescriptor&)’ to ‘void (*)(CommandDescriptor&)’ [-fpermissive] 

在我的理解中提到非-const對象應該可用作引用const對象參數的參數。因此,指向接受非const對象引用的函數的類型指針的參數應該超過滿足(並且做隱式轉換)指向函數的類型指針參數,該參數甚至可以接受const對象引用。

我在哪裏錯了?

+1

你有一個「指向某個東西」並且想傳遞一個「指向其他東西的指針」。在這種情況下,即使指向類型相似,也沒有隱式轉換。 –

回答

2

void (*)(const CommandDescriptor&)void (*)(CommandDescriptor&)是兩個完全不同的,不相關的類型。

有關於const規則很簡單:可以轉換爲X const*X**可轉換爲X const * const *等。同樣的事情與參考。沒有別的東西是允許的

請注意,規則不允許在該類型的任何位置任意添加或刪除const,例如,X**不能轉換爲X const **。對於函數參數的位置也是如此:您不能在那裏添加或刪除const以獲得兼容的類型。

是否可以擴展這些規則,以便它們適應像您這樣的病例並保持一致?可能是這樣。但他們不是。

1

C++有一組有限的情況,其中const可以隱式添加或刪除。你遇到了無法完成的事情。其原因可能很簡單,因爲「描述那些安全的案例會很困難,標準作者是懶惰和保守的」。

作爲變通,你可以這樣做:

CommandLogFilter bob(
    logServer, 
    parent, 
    [](CommandDescriptor &descriptor) { 
    return printCommandReceived(descriptor); 
    } 
); 

爲無狀態的lambda表達式可以隱式轉換到一個指針匹配他們的簽名功能。

我不喜歡在那裏顯式簽名,但是沒有辦法對模板「auto」lambdas做類似的事情,並且不幸的是簽名被推導出來。

相關問題