我一直在听C++中的仿函数.有人可以给我一个关于它们是什么的概述以及在什么情况下它们会有用吗?
我正在寻找涉及将C++模板函数作为参数传递的规则.
这得到了C++的支持,如下例所示:
#include <iostream>
void add1(int &v)
{
v+=1;
}
void add2(int &v)
{
v+=2;
}
template <void (*T)(int &)>
void doOperation()
{
int temp=0;
T(temp);
std::cout << "Result is " << temp << std::endl;
}
int main()
{
doOperation<add1>();
doOperation<add2>();
}
Run Code Online (Sandbox Code Playgroud)
然而,了解这种技术很困难.谷歌搜索"作为模板参数的功能"不会导致太多.令人惊讶的是,经典的C++模板完整指南也没有讨论它(至少不是我的搜索).
我的问题是这是否是有效的C++(或者只是一些广泛支持的扩展).
另外,在这种模板调用过程中,有没有办法允许具有相同签名的仿函数与显式函数互换使用?
以下就不能在上面的程序中工作,至少在视觉C++,因为语法显然是错误的.能够为仿函数切换函数是很好的,反之亦然,类似于如果要定义自定义比较操作,可以将函数指针或函子传递给std :: sort算法.
struct add3 {
void operator() (int &v) {v+=3;}
};
...
doOperation<add3>();
Run Code Online (Sandbox Code Playgroud)
指向一个或两个Web链接的指针,或C++模板书中的页面将不胜感激!
在向某人解释什么是类型类X时,我很难找到正好是X的数据结构的好例子.
所以,我请求示例:
我认为Monad到处都有很多例子,但Monad的一个很好的例子与之前的例子有一些关系可以完成图片.
我寻找彼此相似的示例,区别仅在于属于特定类型类的重要方面.
如果有人能够设法在这个层次结构的某个地方隐藏一个Arrow的例子(它是在Applicative和Monad之间吗?),那也会很棒!
F#派生自OCaml,但缺少或添加了哪些主要项目?具体来说,我很好奇可用于学习OCaml的资源是否对想要学习F#的人有用.
map :: (a -> b) -> [a] -> [b]
fmap :: Functor f => (a -> b) -> f a -> f b
liftM :: Monad m => (a -> b) -> m a -> m b
Run Code Online (Sandbox Code Playgroud)
为什么我们有三个不同的功能,基本上是一样的?
这不是lambda函数问题,我知道我可以将lambda赋给变量.
允许我们声明,但不在代码中定义函数是什么意思?
例如:
#include <iostream>
int main()
{
// This is illegal
// int one(int bar) { return 13 + bar; }
// This is legal, but why would I want this?
int two(int bar);
// This gets the job done but man it's complicated
class three{
int m_iBar;
public:
three(int bar):m_iBar(13 + bar){}
operator int(){return m_iBar;}
};
std::cout << three(42) << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以我想知道的是为什么C++会允许two
哪些看似无用,three
哪个看起来更复杂,但却不允许one
?
编辑:
从答案中可以看出,代码内声明可能能够防止命名空间污染,我希望听到的是为什么声明函数的能力已被允许,但是不允许定义函数的能力.
我一直在读类别理论中的单子.monads的一个定义使用一对伴随函子.monad是使用这些仿函数的往返定义的.显然,在类别理论中,附加是非常重要的,但我没有看到关于伴随函子的Haskell monad的任何解释.有没有人给它一个想法?
我是Haskell的新手,我正在阅读有关仿函数和应用函子的内容.好吧,我理解仿函数以及如何使用它们,但我不明白为什么应用仿函数是有用的以及我如何在Haskell中使用它们.你能用一个简单的例子向我解释为什么我需要应用仿函数吗?
最近关于集合的讨论出现了,在Scala中支持该zip
方法以及如何导致bug,例如
scala> val words = Set("one", "two", "three")
scala> words zip (words map (_.length))
res1: Set[(java.lang.String, Int)] = Set((one,3), (two,5))
Run Code Online (Sandbox Code Playgroud)
我认为很明显Set
s不应该支持一个zip
操作,因为元素没有被排序.但是,有人认为这个问题Set
不是真正的算子,也不应该有map
方法.当然,你可以通过映射集合来解决自己的问题.现在切换到Haskell,
data AlwaysEqual a = Wrap { unWrap :: a }
instance Eq (AlwaysEqual a) where
_ == _ = True
instance Ord (AlwaysEqual a) where
compare _ _ = EQ
Run Code Online (Sandbox Code Playgroud)
现在在ghci
ghci> import Data.Set as Set
ghci> let nums = Set.fromList [1, 2, 3]
ghci> Set.map unWrap $ Set.map …
Run Code Online (Sandbox Code Playgroud)