簡體   English   中英

使用`std :: function <void(…)> `調用非空函數

[英]Using `std::function<void(…)>` to call non-void function

前一段時間我使用std::function非常像這樣:

std::function<void(int)> func = [](int i) -> int { return i; };

基本上,我這樣做是因為我想在std::function存儲不同的函數對象,但我不想限制這些函數的返回類型。 由於這似乎有效,我接受了它。 但我不相信它是安全的,我也無法找到任何文件。 有誰知道這種用法是否合法? 或者更一般地說,對於可以安全地分配給std::function的對象的規則是什么?

編輯

為了澄清,我關心的問題是lambda函數返回一個int ,而func用return類型void聲明。 我不確定這是否正常,特別是在調用func()

您的代碼具有未定義的行為。 它可能會或可能不會像您期望的那樣工作。 它有未定義行為的原因是因為20.8.11.2.1 [func.wrap.func.con] / p7:

要求: F應為CopyConstructible 對於參數類型ArgTypesf應為Callable(20.8.11.2)並返回類型R

對於f為返回類型R Callable, f必須返回一些可隱式轉換為std::function的返回類型的東西(在你的情況下為void )。 並且int不能隱式轉換為void

我希望您的代碼能夠適用於大多數實現。 但是至少在一個實現( libc ++ )上,它無法編譯:

test.cpp:7:30: error: no viable conversion from 'int (int)' to 'std::function<void (int)>'
    std::function<void(int)> ff = f;
                             ^    ~

具有諷刺意味的是,這種行為的基本原理源於另一個SO問題

另一個問題是std::function用法存在問題。 該問題的解決方案涉及讓實現在編譯時強制執行Requires:子句。 相反,這個問題的解決方案是禁止實現強制執行Requires:子句。

您的用例根據標准明確定義。

您正在從可調用對象[1]構造一個std::function

§20.8.11.2.1/ 7:

 template<class F> function(F f); 

要求:F應為CopyConstructible。 對於參數類型ArgTypes,f應為Callable(20.8.11.2)並返回R類型。

那你的f可以贖回嗎?

§20.8.11.2/ 2說:

類型F的可調用對象f對於參數類型ArgTypes是Callable,如果表達式INVOKE (f, declval<ArgTypes>()..., R)被認為是未評估的操作數(第5條),則返回類型R.形成良好(20.8.2)。

INVOKE的定義是:

§20.8.2

  1. 定義INVOKE (f, t1, t2, ..., tN)如下:...處理成員函數/ var指針的東西...... - f(t1, t2, ..., tN)在所有其他情況下。

  2. INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN)隱式轉換為R INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN)

並且因為任何類型都可以隱式轉換為void ,所以使用符合標准的編譯器,您的代碼應該沒問題。 正如下面的litb所指出的,沒有隱含的轉換為void,所以這個定義不明確。

[1]:我認為lambda在這里算作一個可調用的對象,雖然我沒有參考。 您的lambda也可以用作函數指針,因為它不捕獲任何上下文

這看起來對於匿名函數可能沒問題。

引自http://www.alorelang.org/release/0.5/doc/std_function.html (這不是來自C ++標准庫,但看起來他們使用的東西類似於綁定到C ++)

只能使用函數定義,匿名函數表達式或使用點(。)運算符訪問綁定方法來創建函數對象。

另一種可能的方法是將函數指針存儲在auto中,如下所示: http//en.wikipedia.org/wiki/Anonymous_function (C ++ section)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM