c – 如何使这些std :: function参数明确无误?
发布时间:2020-12-16 09:54:39 所属栏目:百科 来源:网络整理
导读:传递lambda时,以下函数重载是不明确的.我发现std :: function可以是 constructed from most callable types,即使它们的签名不匹配.所以编译器无法分辨使用哪个函数. template typename T void each(std::functionvoid(T) iterator);template typename T void
传递lambda时,以下函数重载是不明确的.我发现std :: function可以是
constructed from most callable types,即使它们的签名不匹配.所以编译器无法分辨使用哪个函数.
template <typename T> void each(std::function<void(T)> iterator); template <typename T> void each(std::function<void(T,id)> iterator); template <typename T> void each(std::function<void(T&)> iterator); template <typename T> void each(std::function<void(T&,id)> iterator); 这里有一些类似的问题,但没有一个能解决我的问题.如何在不改变用法的情况下解决歧义?更重要的是,当时我必须明确提到模板类型.有没有解决的办法? 解决方法
其中一半是
LWG issue 2132,从重载决策中删除std :: function的构造函数,除非参数实际上可以为指定的参数类型调用.这需要表达SFINAE支持来实现,VC没有.
问题的另一半是重载解决: #include<functional> #include<iostream> struct id {}; template <typename T> void each(std::function<void(T)> ){ std::cout << __PRETTY_FUNCTION__ << std::endl; } template <typename T> void each(std::function<void(T,id)> ){ std::cout << __PRETTY_FUNCTION__ << std::endl; } template <typename T> void each(std::function<void(T&)> ){ std::cout << __PRETTY_FUNCTION__ << std::endl; } template <typename T> void each(std::function<void(T&,id)> ){ std::cout << __PRETTY_FUNCTION__ << std::endl; } int main() { each<int>([](int,id){}); } 有一个实现LWG2132,this code prints的库,也许令人惊讶: void each(std::function<void(T&,id)>) [with T = int] 为什么?首先,可以构造一个std :: function< void(T&,id)>来自[](int,id){}.毕竟,后者可以使用类型为int的左值来调用. 第二,在 template <typename T> void each(std::function<void(T,id)>); template <typename T> void each(std::function<void(T&,id)>); 第二种方法比功能模板的部分排序规则更专业,因此总是通过重载分辨率来选择. 一种可能的解决方案是通过操纵lambda的operator()的类型来提取签名: template<class T> struct mem_fn_type; template<class R,class C,class... T> struct mem_fn_type<R(C::*)(T...)> { using type = std::function<R(T...)>; }; template<class R,class... T> struct mem_fn_type<R(C::*)(T...) const> { using type = std::function<R(T...)>; }; // optional extra cv-qualifier and ref-qualifier combos omitted // since they will never be used with lambdas // Detects if a class is a specialization of std::function template<class T> struct is_std_function_specialization : std::false_type {}; template<class T> struct is_std_function_specialization<std::function<T>> : std::true_type{}; // Constrained to not accept cases where T is a specialization of std::function,// to prevent infinite recursion when a lambda with the wrong signature is passed template<class T> typename std::enable_if<!is_std_function_specialization<T>::value>::type each(T func) { typename mem_fn_type<decltype(&T::operator())>::type f = func; each(f); } 这不适用于通用lambda(其operator()是模板)或任意函数对象(可能有任意多个operator()重载). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- ruby-on-rails – Ruby / Rails:使用`separator:’ – ‘
- c# – ListBox.DataSource集合与ListBox.Items之间的区别?
- Oracle 11g ORA-00314、ORA-00312 redo日志与控制文件seque
- 通配符或正则表达式节点表示中间件上的挂载路径
- PhoneGap/SQLite对CacheGroups,Caches,Origins和DeletedCac
- 有没有人在C / WinAPI中有类似FileSystemWatcher的类?
- swift基础回顾 (二)
- H3C 三层交换机 端口及端口安全相关
- cocos2d-x main重定义
- Vue computed计算属性的使用方法