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::functiontemplate<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 passedtemplate<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()重载).
总结以上是内存溢出为你收集整理的c – 如何使这些std :: function参数明确无误?全部内容,希望文章能够帮你解决c – 如何使这些std :: function参数明确无误?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)