我一直在听C++中的仿函数.有人可以给我一个关于它们是什么的概述以及在什么情况下它们会有用吗?
在我们的代码中,我们有很多这种模式的情况:
class outerClass
{
struct innerStruct
{
wstring operator()( wstring value )
{
//do something
return value;
}
};
void doThing()
{
wstring initialValue;
wstring finalValue = innerStruct()( initialValue );
}
};
Run Code Online (Sandbox Code Playgroud)
这有什么好处:
class outerClass
{
wstring changeString( wstring value )
{
//do something
return value;
}
void doThing()
{
wstring initialValue;
wstring finalValue = changeString( initialValue );
}
};
Run Code Online (Sandbox Code Playgroud) 我最近对仿函数很兴奋,并且一直在使用它们.然后情况出现了,我需要我的仿函数执行两个不同的操作,我想到为我的仿函数添加另一个方法(不重载()运算符).这是不是不好的做法我不确定(也许你可以告诉我),但它让我思考为什么我首先使用仿函数而不仅仅是对象.所以我的问题是:
有没有什么特别的重载()运算符或者它是否比使用普通的命名方法更具语法吸引力?
更新:
首先,我知道为什么函子可能比其他问题中解释的函数指针更可取.我想知道为什么它们可以优于具有命名方法的对象.
其次,至于我何时想要使用另一个可能命名的函子方法的例子:基本上我有两个函数,一个计算一个叫做图形分区的模块性的东西compute_modularity(),另一个用于计算一些变化后的模块化增益分区compute_modularity_gain().我以为我可以将这些函数作为同一仿函数的一部分传递给优化算法,并将增益作为命名函数.我不只是传递了两个函子到算法,其原因是,我想执行这一compute_modularity_gain()只与使用一起选择compute_modularity(),而不是另一个函子如compute_stability()(应该仅被使用compute_stability_gain().换句话说,增益功能必须紧密加上它的兄弟功能.如果还有其他方法我可以执行这个约束,那么请告诉我.
我已经看到了operator()STL容器的使用,但它是什么,你什么时候使用它?
正如另一个问题所建议的那样,我使用一些using语句并unique_ptr使用OpenSSL 。没有它,代码将变得非常丑陋,我不是goto语句的忠实拥护者。
到目前为止,我已尽可能地更改了代码。这是我使用的示例:
using BIO_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using X509_ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
using PKCS7_ptr = std::unique_ptr<PKCS7, decltype(&::PKCS7_free)>;
...
BIO_ptr tbio(BIO_new_file(some_filename, "r"), ::BIO_free);
Run Code Online (Sandbox Code Playgroud)
现在我需要a STACK_OF(X509),我不知道,是否也可以使用unique_ptr。我正在寻找与下面类似的东西,但这不起作用。
using STACK_OF_X509_ptr = std::unique_ptr<STACK_OF(X509), decltype(&::sk_X509_free)>;
Run Code Online (Sandbox Code Playgroud)
我也尝试过Functor:
struct StackX509Deleter {
void operator()(STACK_OF(X509) *ptr) {
sk_X509_free(ptr);
}
};
using STACK_OF_X509_ptr = std::unique_ptr<STACK_OF(X509), StackX509Deleter>;
STACK_OF_X509_ptr chain(loadIntermediate(cert.string()));
Run Code Online (Sandbox Code Playgroud)
编译器接受这一点,然后应用程序运行。只是一个问题:在unique_ptrs上面显示的另一个问题中,我总是指定了第二个参数,所以我敢打赌我缺少了一些东西:
STACK_OF_X509_ptr chain(loadIntermediate(cert.string()), ??????);
Run Code Online (Sandbox Code Playgroud)
如何使用C ++ unique_ptr和OpenSSL STACK_OF(X509)*?
我研究过运算符函数的格式是
(return value)operator[space]op(arguments){implementation}
Run Code Online (Sandbox Code Playgroud)
但是,在std::reference_wrapper实现中,有一个声明为的运算符重载函数operator T& () const noexcept { return *_ptr; }.
这个操作符与T& operator () const noexcept { return *_ptr; }?不同?如果两者不同,那么第一个的用途是什么?
我有关于vector中for_each的问题,代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector(3,4);
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
应该for_each()的第三个参数是函数名吗?如果我们传递结构的名称,这是如何工作的?
根据这个问题的第一个答案,下面的仿函数应该能够在传递之后保留一个值foreach(我无法struct Accumulator在示例中进行编译,因此构建了一个类).
class Accumulator
{
public:
Accumulator(): counter(0){}
int counter;
void operator()(const Card & c) { counter += i; }
};
Run Code Online (Sandbox Code Playgroud)
示例用法(根据示例)
// Using a functor
Accumulator acc;
std::for_each(_cards.begin(), _cards.end(), acc);
// according to the example - acc.counter contains the sum of all
// elements of the deque
std::cout << acc.counter << std::endl;
Run Code Online (Sandbox Code Playgroud)
_cards实现为std::deque<Card>.无论多长时间_cards,完成acc.counter后为零for_each.当我在调试器中单步执行时,我可以看到计数器递增,但是,它是否与acc通过值传递有关?