无法通过 std::ref() 使用 auto& 参数调用 std::invoke()
Cannot call std::invoke() with auto& parameter via std::ref()
我正在尝试创建一个 Invoker
对象,该对象同时存储函数和一组函数的参数 - ast by value(用于螺纹(。 Invoker::operator()()
将使用复制的参数调用存储的函数。
到目前为止,一切都很好,直到人们尝试使用auto&
通过CC_3传递参数。具体而言,此代码应起作用,而是与给定的错误消息没有编译:
int var = 0;
Invoker{
[](auto& r) {
printf("%dn", r);
}, std::ref(var)
}();
我希望它的工作原理类似于std::thread
在此示例中的工作方式。错误消息是:
test.cpp:65:14: error: no matching function for call to ‘invoke(std::__tuple_element_t<0, std::tuple<main()::<lambda(auto:1&)>, std::reference_wrapper<int> > >, std::__tuple_element_t<1, std::tuple<main()::<lambda(auto:1&)>, std::reference_wrapper<int> > >)’ std::invoke(std::get<Indicies>(std::move(args))...); ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我当前的Invoker
类:
template<typename... Args>
struct Invoker {
std::tuple<std::decay_t<Args>...> args;
explicit Invoker(Args... args)
: args(std::forward<Args>(args)...)
{ }
template<size_t... Indices>
void _Invoke(std::index_sequence<Indices...>) {
std::invoke(std::get<Indices>(std::move(args))...);
}
void operator()() {
_Invoke(std::make_index_sequence<std::tuple_size_v<decltype(args)>>{});
}
};
/* Invoker deduction guide (perfectly forward any parameters with full type!) */
template<typename Function, typename... Args>
Invoker(Function&&, Args&&...) -> Invoker<Function&&, Args&&...>;
有关此问题的在线版本,请参见此处。错误消息表明,当应为int&
时,推论的auto&
类型为std::reference_wrapper<int>&
。不幸的是,我无法提出解决这个问题的解决方案。
编辑:
如评论所示,表达式
int var = 5;
std::thread{ [](auto& r) { printf("%dn", r); }, std::ref(var) };
仅使用gcc >= 7.1.0
编译。我很高兴看到有关此主题的详细说明,特别是如果C 标准这是正确的行为。
INVOKE
通常不会取消包装reference_wrapper
参数;它们被用作IS(一个例外,此处无关:如果将reference_wrapper
作为第一个参数的成员调用指针,则该参数是未包装的(。因此,invoke([](auto&){}, std::ref(var));
将尝试使用RVALUE reference_wrapper
调用Lambda,该lambda试图将RVALUE绑定到LVALUE参考。
std::thread
观察到的行为是已固定的LIBSTDC 错误。简而言之,libstdc 的 std::thread
将提供的参数存储在tuple
中,该参数(错误地(用make_tuple
构建(它取消了reference_wrapper
s(。
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- 为什么 std::function 可以作为 std::not2 的参数?
- 传递给std::function template的template参数究竟代表什么
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 将函数参数"const char*"转换为"std::string_view"是
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 为什么 std::绑定错误参数可以成功?
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- std::vector 没有重载函数的实例与参数列表匹配
- std::span<const T> 作为函数模板中的参数
- SegFault 同时使用 std::string::operator+= 和函数作为参数
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 在构造函数中使用可变参数初始化 std::tuple
- 为什么我不能将引用作为 std::async 的函数参数传递
- 转发变量参数列表以模拟 std::thread
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- "std::shared_ptr":不是参数"_Ty"的有效模板类型参数
- 可变参数模板参数扩展 类型为 std::function 的类成员