- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一个高阶函数 map
类似于 STL for_each
, 并映射一个 std::function
vector
上的对象的东西。
template<class T, class U>
vector<U> map(function<U (T)> f, vector<T> xs) {
vector<U> ret;
for (auto &x: xs)
ret.push_back(f(x));
return ret;
}
现在,我想让这个高阶函数同时获取 function<int (const vector<T>&)>
类型的两个对象和 function<int (vector<T>)>
,如随附的最小示例所示。
问题是function<int (const vector<T>&)>
和 function<int (vector<T>)>
似乎可以相互转换(见 head
和 head2
),但 map
不会采用 const 引用版本 function<int (const vector<int>&)>
(见 Q1
)。
可以告诉map
接受带有显式转换的 const 引用版本( Q2
),但这相当麻烦。
我想知道,一般来说,是否可以编写函数 deref
从 function<int (const vector<T>&)>
中删除 const 引用并返回 function<int (vector<T>)>
?
(如果上面是可能的,那么我不必为 const refs 编写两个相同的 map 重载/实现)。
谢谢。
#include <vector>
#include <functional>
using namespace std;
template<class T, class U>
vector<U> map(function<U (T)> f, vector<T> xs) {
vector<U> ret;
for (auto &x: xs)
ret.push_back(f(x));
return ret;
}
int main() {
vector<vector<int>> m;
function<int (const vector<int>&)> head = [](const vector<int>& a) {return a[0];};
function<int (const vector<int>&)> head1 = [](vector<int> a) {return a[0];}; //conversion OK
function<int (vector<int>)> head2 = [](const vector<int>& a) {return a[0];}; //conversion OK
map(head2,m); //OK
map(head,m); //Q1: problem line, implicit conversion NOT OK
map(function<int (vector<int>)>(head),m); //Q2: explicit conversion OK
map(deref(head),m); //Q3: ??How-to, deref takes a std::function f and returns a function with const ref removed from its signature
return 0;
}
--- 编辑 ---
我对 deref
特别感兴趣like 函数或元函数,可以从 std::function
的类型签名中删除 const ref对象,这样我至少可以做Q2
自动。
我知道,正如@Brian 和@Manu 正确指出的那样,使用 std::function
指定类型不是常规的,但我想知道我上面问的是否可行。 个人,我认为代码为 std::function
更清晰,考虑到泛型函数类型 Func<T1, T2, T3, ...,Tn, Tresult>
在 C# 中使用。这是如果类型删除的成本是可以容忍的。
我完全同意 c++ 可以推断返回类型并在类型错误时给出错误消息。也许这只是一个口味问题,我更愿意在编写函数签名时把它拼出来。
最佳答案
我明白你为什么使用 std::function
:你必须知道转换的返回类型才能创建 vector ,对吧?
但请考虑一种完全不同的方法。给定元函数 std::result_of
您可以计算函数调用的结果类型,因此只需编写:
template<typename F , typename CONTAINER , typename T = typename std::result_of<F(typename CONTAINER::value_type)>::type>
std::vector<T> map( F f , CONTAINER&& container )
{
std::vector<T> result;
for( auto& e : container )
result.emplace_back( f( e ) );
return result;
}
不要滥用 std::function
:永远想想 std::function
做了什么(即类型删除),不要'不要将其用作通用函数类型。
依赖鸭子类型而不是耦合类型:别担心,如果出现问题,它也不会编译。
适用于任何标准库容器,因为我们使用 value_type
特征提取元素类型,而不是使用 std::vector
直接。
代码更加清晰和高效,这都是因为减少了 std::function
的使用。
使用 std::function
您可以在几行代码中编写类似于 Boost.OverloadedFunction 的内容:
template<typename F , typename... Fs>
struct overloaded_function : public std_function<F> , public std_function<Fs>...
{
overloaded_function( F&& f , Fs&&... fs ) :
std_function<F>{ f },
std_function<Fs>{ fs }...
{}
};
其中 std_function
是一个元函数,它给定一个函数类型 F
返回带有 F 签名的
。我把它留给读者作为游戏/挑战。std::function
实例
仅此而已。使用类似 make 的功能对其进行改进:
template<typename F , typename... Fs>
overloaded_function<F,Fs...> make_overloaded_function( F&& f , Fs&&... fs )
{
return { std::forward<F>( f ) , std::forward<Fs>( fs )... };
}
你准备好了:
auto f = make_overloaded_function( [](){ return 1; } ,
[](int,int){ return 2; } ,
[](const char*){ return 3; } );
f(); //Returns 1
f(1,2); //Returns 2
f("hello"); //Returns 3
好的,让我试试:std::decay
元函数在将参数按值传递给给定类型时应用衰减完成。这包括删除 cv 限定符、删除引用等。因此,像您这样的元函数可能是采用函数签名类型并将衰减应用于其所有参数的东西:
template<typename F>
struct function_decay;
template<typename R typename... ARGS>
struct function_decay<R(ARGS...)>
{
using type = R(typename std::decay<ARGS>::type...);
};
这应该可以完成工作。
我写这个是因为你在评论中明确要求它,但我强烈建议你使用我最初向你展示的替代方案,因为它与你的方式相比有很多优势。
也就是说,我希望这个答案有助于解决您的问题。
关于c++ - 是否可以允许一种 std::function 类型接受具有不同签名的 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24561846/
我有一个 ASP.NET 网站,我希望只允许 AD 组中的用户访问该网站。我正在使用如下的 web.config 片段,但这似乎不起作用:
仅当选中所有框时才应禁用“允许”按钮。我该怎么做?我已经完成了 HTML 部分,如下所示。如何执行其中的逻辑部分?即使未选中一个复选框,也应禁用“允许”按钮
当前有一个Navigator.push(context,route),但是上下文部分返回了错误,在尝试调试后,我发现问题是因为我在调用一个函数而不是直接将home设置为widget树。但是现在我不确定
这是我的邮政编码正则表达式 ^[a-zA-Z0-9]{1,9}$ 但不允许 A-12345。如何更改 - 也将被允许的正则表达式? 最佳答案 在字符集的开头或结尾添加-([...]): ^[-a-zA
我目前正在建立我的网站,但遇到了一个问题 JavaScript 中的混合内容阻止 当我尝试加载和显示来自 的图像和页面时,Chrome、Mozilla 和 Explorer 会发生这种情况http 我
我见过使用: [mysqld] bind-address = 255.112.324.12 允许远程访问单个 IP。我如何允许从 mysql 远程访问所有 IP? 最佳答案 如果你想允许它用于所
我想知道是否可以使用模板实现某些功能。我想要做的是允许特定的“复制构造函数和赋值运算符”从一个模板到另一个模板并禁用其他模板。 我想我只完成了一件我想要的事情,所以我提供了下面的类(class)。对于
这个问题在这里已经有了答案: How to validate an email address in PHP (15 个答案) 关闭 2 年前。 正则表达式让我大吃一惊。我如何更改此设置以验证带有加
解析可以采用以下格式之一的日期的最佳方法是什么 "dd-MM-yyyy HH:mm" "dd/MM/yyyy HH:mm" "dd.MM.yyyy HH:mm" 无需创建 3 个 SimpleD
我们知道,下面的代码格式不正确,因为成员 x 在依赖的基类中。但是,将指定行上的 x 更改为 this->x 将修复错误。 template struct B { int x; }; tem
如果能帮助我理解“Java 并发实践”中的以下内容,我将不胜感激: Calling an overrideable instance method(one that is neither privat
此时如果上传一个不在预定义的安全扩展名列表,如.lrc,会报错: File type does not meet security guidelines. Try another. 解决此问题有
我有一个运行韵律,可以为我的几个域和一个 friend 域处理 XMPP。我 friend 域中的一位用户(他的妻子)想更改她的密码(实际上她忘记了她,所以我会用 prosodyctl 设置一个,然后
使用 nginx,您可以允许和拒绝范围和 ips (https://www.nginx.com/resources/admin-guide/restricting-access/)。使用realip模
什么是一些好的克里金法/插值想法/选项,可以让重度权重的点在绘制的 R map 上的轻权重点上流血? 康涅狄格州有八个县。我找到了质心并想绘制这八个县中每个县的贫困率。其中三个县人口稠密(约 100
我正在使用 virtualbox + ubuntu + vagrant . 但是我不能ping或 wget任何网址。请指导我如何允许虚拟机访问我的主机的互联网? 最佳答案 这对我有用。 使用此配置 V
标题可能有点令人困惑,所以让我向您解释一下。 在 Swift 中,我们可以拥有带有默认参数值的函数,例如: func foo(value: Int = 32) { } 我们也可以有 In-Out 参数
有TextView1 和TextView2。 TextView2 应该 float 在 TextView1 的右侧。只要两个 TextView 的总宽度不使 TextView2 与右侧的框重叠,Tex
使用 Magento 收集方法 addFieldToFilter 时是否可以允许按 NULL 值进行过滤?我想选择集合中具有自定义属性的所有产品,即使没有为该属性分配任何值。 最佳答案 您不需要使用
我正试图从 .htaccess 文件中的规则中“排除”一个目录(及其所有文件夹)... 不确定这是否可能? .htaccess 文件是这样的: Order Allow,Deny Deny from a
我是一名优秀的程序员,十分优秀!