這是我嘗試編譯的代碼的淡化示例:
#include <iostream>
#include <functional>
template <class F>
auto foo(F&& fun)
{
return [callback = std::forward<F>(fun)](auto&&... args) {
std::invoke(callback, std::forward<decltype(args)>(args)...);
};
}
int main()
{
std::string cur("running"), target("ok");
foo([s1 = cur, s2 = target](std::string const& arg) /*mutable*/ {
if (s1 == arg)
{
std::cout << s1 << std::endl;
}
})("not ok");
return 0;
}
簡單地說,我有一個foo接受可呼叫物件的函式,并且應該從它們構建一個新的可呼叫物件。就示例而言,上面我只是呼叫fun引數,但在實際情況下,對可呼叫物件進行了一些修飾,并將結果放入在某些條件下呼叫此類“操作”的資料結構中。
這個例子編譯并運行得很好。這個問題時,試圖通過可變lambda運算式來體現foo。當我取消注釋mutable上面的關鍵字時,出現以下編譯錯誤:
main.cpp: In instantiation of 'foo<main()::<lambda(const string&)> >(main()::<lambda(const string&)>&&)::<lambda(auto:1&& ...)> [with auto:1 = {const char (&)[7]}]':
main.cpp:21:7: required from here
main.cpp:8:20: error: no matching function for call to 'invoke(const main()::<lambda(const string&)>&, const char [7])'
8 | std::invoke(callback, std::forward<decltype(args)>(args)...);
| ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from main.cpp:2:
/usr/local/include/c /11.2.0/functional:94:5: note: candidate: 'template<class _Callable, class ... _Args> std::invoke_result_t<_Callable, _Args ...> std::invoke(_Callable&&, _Args&& ...)'
94 | invoke(_Callable&& __fn, _Args&&... __args)
| ^~~~~~
/usr/local/include/c /11.2.0/functional:94:5: note: template argument deduction/substitution failed:
In file included from /usr/local/include/c /11.2.0/bits/move.h:57,
from /usr/local/include/c /11.2.0/bits/nested_exception.h:40,
from /usr/local/include/c /11.2.0/exception:148,
from /usr/local/include/c /11.2.0/ios:39,
from /usr/local/include/c /11.2.0/ostream:38,
from /usr/local/include/c /11.2.0/iostream:39,
from main.cpp:1:
/usr/local/include/c /11.2.0/type_traits: In substitution of 'template<class _Fn, class ... _Args> using invoke_result_t = typename std::invoke_result::type [with _Fn = const main()::<lambda(const string&)>&; _Args = {const char (&)[7]}]':
/usr/local/include/c /11.2.0/functional:94:5: required by substitution of 'template<class _Callable, class ... _Args> std::invoke_result_t<_Callable, _Args ...> std::invoke(_Callable&&, _Args&& ...) [with _Callable = const main()::<lambda(const string&)>&; _Args = {const char (&)[7]}]'
main.cpp:8:20: required from 'foo<main()::<lambda(const string&)> >(main()::<lambda(const string&)>&&)::<lambda(auto:1&& ...)> [with auto:1 = {const char (&)[7]}]'
main.cpp:21:7: required from here
/usr/local/include/c /11.2.0/type_traits:2933:11: error: no type named 'type' in 'struct std::invoke_result<const main()::<lambda(const string&)>&, const char (&)[7]>'
2933 | using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
| ^~~~~~~~~~~~~~~
知道這是為什么嗎?我也可以foo接受可變的 lambda 運算式嗎?
uj5u.com熱心網友回復:
只需添加mutable到 lambda 中foo:
template <class F>
auto foo(F&& fun)
{
return [callback = std::forward<F>(fun)](auto&&... args) mutable {
//^^^
std::invoke(callback, std::forward<decltype(args)>(args)...);
};
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/317122.html
下一篇:我將如何解決它不是一個參考陣列?
