我一直在听C++中的仿函数.有人可以给我一个关于它们是什么的概述以及在什么情况下它们会有用吗?
我想创建一个函数对象,它还具有一些属性.例如在JavaScript中我会这样做:
var f = function() { }
f.someValue = 3;
Run Code Online (Sandbox Code Playgroud)
现在在TypeScript中,我可以将其描述为:
var f: { (): any; someValue: number; };
Run Code Online (Sandbox Code Playgroud)
但是我不能在不需要演员的情况下构建它.如:
var f: { (): any; someValue: number; } =
<{ (): any; someValue: number; }>(
function() { }
);
f.someValue = 3;
Run Code Online (Sandbox Code Playgroud)
如果没有演员,你会如何建立这个?
根据Scott Meyers的说法,C++在C上闪耀的一个领域是函数对象比函数指针更快.他说这是因为函数对象是内联的,这会提高速度.
我有两个问题:
我们如何验证函数对象实际上是内联的?我们能否在实践中验证这一点?
函数对象的内联是否依赖于我们使用的编译器,还是所有编译器的行为都是这样的?
在Bjarne Stroustrup的主页(C++ 11 FAQ)中:
struct X { int foo(int); };
std::function<int(X*, int)> f;
f = &X::foo; //pointer to member
X x;
int v = f(&x, 5); //call X::foo() for x with 5
Run Code Online (Sandbox Code Playgroud)
它是如何工作的?std :: function如何调用foo成员函数?
模板参数int(X*, int),是&X::foo从转换成员函数指针到一个非成员函数指针?!
(int(*)(X*, int))&X::foo //casting (int(X::*)(int) to (int(*)(X*, int))
Run Code Online (Sandbox Code Playgroud)
澄清:我知道我们不需要使用任何指针来使用std :: function,但我不知道std :: function的内部如何处理成员函数指针和非成员函数之间的这种不兼容性指针.我不知道标准如何允许我们实现像std :: function这样的东西!
在C++ 17中,实现一个overload(fs...)函数是很容易的,在fs...满足任意数量的参数的情况下FunctionObject,它返回一个行为类似于重载的新函数对象fs....例:
template <typename... Ts>
struct overloader : Ts...
{
template <typename... TArgs>
overloader(TArgs&&... xs) : Ts{forward<TArgs>(xs)}...
{
}
using Ts::operator()...;
};
template <typename... Ts>
auto overload(Ts&&... xs)
{
return overloader<decay_t<Ts>...>{forward<Ts>(xs)...};
}
int main()
{
auto o = overload([](char){ cout << "CHAR"; },
[](int) { cout << "INT"; });
o('a'); // prints "CHAR"
o(0); // prints "INT"
}
Run Code Online (Sandbox Code Playgroud)
由于上面的overloader继承Ts...,它需要复制或移动函数对象才能工作.我想要一些提供相同重载行为的东西,但只引用传递的函数对象.
我们称之为假设函数ref_overload(fs...).我的尝试正在使用std::reference_wrapper …
c++ overloading function-object template-meta-programming c++17
我最近发现在C++中你可以以一种奇怪的方式重载"函数调用"操作符,你需要编写两对括号来执行此操作:
class A {
int n;
public:
void operator ()() const;
};
Run Code Online (Sandbox Code Playgroud)
然后以这种方式使用它:
A a;
a();
Run Code Online (Sandbox Code Playgroud)
什么时候有用?
这句话说什么:
return static_cast<Hasher &>(*this)(key);
Run Code Online (Sandbox Code Playgroud)
?
我无法判断*thisor是否key被传递给static_cast. 我环顾四周,找到了这个答案,但与我所坚持的不同,第一对括号内没有任何内容。
我刚刚阅读了经典书籍"Effective C++,3rd Edition",在第20项中,作者得出结论,内置类型,STL迭代器和函数对象类型更适合于传值.我完全理解内置函数和迭代器类型的原因,但为什么函数对象应该是值传递,因为我们知道它仍然是类类型的?
以下片段:
#include <functional>
struct X {
X(std::function<double(double)> fn); // (1)
X(double, double); // (2)
template <class T>
auto operator()(T const& t) const { // (3)
return t.foo();
}
};
int main() {
double a, b;
auto x = X(a, b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
... 当使用- 在OSX和godbolt.org上测试时,无法使用clang(4.0.1)和g++(6.3,7.2)-std=c++14进行编译.
但如果符合以下情况,它编译没有问
(1);double)(3);-> decltype(t.foo()))(3);-std=c++1z(感谢@bolov).也许有一些明显我在这里失踪的东西......这段代码有什么问题吗?这是一个错误吗?
c++ function-object std-function return-type-deduction c++14
在wikipedia 关于函数对象的文章中,它说这些对象在与for_each一起使用时具有性能优势,因为编译器可以"内联"它们.
我对这在这种情况下的意义有点模糊......或者我不好意思说的任何背景.谢谢你的帮助!
function-object ×10
c++ ×9
functor ×3
c++11 ×1
c++14 ×1
c++17 ×1
casting ×1
inlining ×1
overloading ×1
std-function ×1
templates ×1
typescript ×1