我一直在寻找的源代码std::function,并std::bind在GCC-4.7.2,和整个使用成员函数指针,我有些不明白的语法来了.
我不明白的是_Maybe_wrap_member_pointer:
template<typename _Tp, typename _Class>
struct _Maybe_wrap_member_pointer<_Tp _Class::*> // note no comma here
Run Code Online (Sandbox Code Playgroud)
为什么_Tp和之间没有逗号_Class::*?
由于成员函数void foo::bar()(在下面我示例应用程序),你会_Tp和_Class::*决心吗?
下面是我的示例应用程序,它绑定成员函数指针和对象.(我已经提取了与std::bind成员函数的特化/内部相关的源代码)
#include <iostream>
#include <functional>
template<typename T>
struct _Maybe_wrap_member_pointer;
template<typename _Tp, typename _Class>
struct _Maybe_wrap_member_pointer<_Tp _Class::*> // <-- I don't understand this
{ // why not <_Tp, _Class::*>
typedef std::_Mem_fn<_Tp _Class::*> type;
static type __do_wrap(_Tp _Class::* __pm)
{
return type(__pm);
}
};
template<typename _Func, typename... …Run Code Online (Sandbox Code Playgroud) 编辑3:如果我删除第二个createTriangle函数,它的工作原理.那么如何绑定重载函数呢?
我有一个函数,它接受一个带有一个参数的函数对象,如下所示:
int createObject(std::function<void(int)>);
Run Code Online (Sandbox Code Playgroud)
如何用std :: bind调用这个函数?我试过这样的:
createObject(std::bind(&ClassA::createTriangle, std::placeholders::_1, a, b, c, color));
Run Code Online (Sandbox Code Playgroud)
但这给了我一个错误:
候选模板被忽略:无法推断模板参数
ClassA :: createTriangle是一个静态函数.
附加信息:
void ClassA::createTriangle(int id, const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c, const glm::vec3 & col) {
/* ... */
}
int ClassB::createTriangle(const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c, const glm::vec3 & color) {
return classCInstance.createObject(std::bind(&classA::createTriangle, std::placeholders::_1, a, b, c, color));
}
int ClassC::createObject(std::function<void(int)> f) {
f(++id);
return id;
}
Run Code Online (Sandbox Code Playgroud)
ClassA中还有另一个静态createTriangle函数,它具有不同的last参数.那可能是个问题吗?绑定不知道选择哪个createTriangle?它看起来像这样:
void ClassA::createTriangle(int …Run Code Online (Sandbox Code Playgroud) 我得到了这段代码:
template <class FunctionType> class Entry {
std::function<FunctionType> internalFunction;
template<class... Arguments>
auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...)){
if (std::is_same<decltype(internalFunction(arguments...)), void>::value) {
internalFunction(arguments...);
} else {
auto result = internalFunction(arguments...);
return result;
}
}
};
Run Code Online (Sandbox Code Playgroud)
入口类旨在包装std::function. 它适用于所有返回类型,只有一个例外 - void。我无法让它工作。我也试过std::is_void,它不会为 type 的函数返回 true void(...)。对于std::is_same.
如何解决这个问题?
我尝试在多元函数上尝试我的牛顿方法片段并使用std::bind和std::function。但我被一个错误困住了
错误:请求从 'std::_Bind_helper&, int>::type {aka std::_Bind, int))(double, double, double)>}' 转换为非标量类型 'std::function'
此错误消息是什么意思,我应该如何修复我当前的代码?
#include <iostream>
#include<functional>
#include<cmath>
double newton(std::function<double(double)> F, std::function<double(double)> f,
double x=0, int maxiter=1000, double epsilon=0.001)
{
int n = 0;
while((n < maxiter) && (fabs(F(x)) > epsilon))
{
x = x - F(x) / f(x);
n++;
}
return x;
}
// I'd like to fix x and z at 1 and 2 and find root for y
double ftest(double x, double y, double z) …Run Code Online (Sandbox Code Playgroud) 我正在调用一个基于模板的函数,它在函数和结构之间共享一个类型.这段代码有什么问题?编译时为什么会收到错误?
TEST.CPP
#include <functional>
#include <iostream>
template<typename T>
struct mystruct
{
T variable;
};
int myfunc(int x)
{
return 2*x;
}
template<typename T>
T calculate(
mystruct<T> custom_struct,
std::function<T(T)> custom_func)
{
return custom_func(custom_struct.variable);
}
int main()
{
mystruct<int> A;
A.variable=6;
std::cout<<calculate(A,myfunc)<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译结果:
test.cpp:25:31: error: no matching function for call to ‘calculate(mystruct<int>&, int (&)(int))’
std::cout<<calculate(A,myfunc)<<std::endl;
^
Run Code Online (Sandbox Code Playgroud) 尝试使用std :: function和std :: bind绑定方法时遇到问题.
在我的CommunicationService类中:
this->httpServer->BindGET(std::bind(&CommunicationService::ManageGETRequest, this, std::placeholders::_1));
Run Code Online (Sandbox Code Playgroud)
CommunicationService :: ManageGetRequest签名:
MessageContent CommunicationService::ManageGetRequest(std::string uri, MessageContent msgContent)
Run Code Online (Sandbox Code Playgroud)
BindGET签名:
void RESTServer::BindGET(RequestFunction getMethod)
Run Code Online (Sandbox Code Playgroud)
RequestFunction typedef:
typedef std::function<MessageContent(std::string, MessageContent)> RequestFunction;
Run Code Online (Sandbox Code Playgroud)
BindGET上的错误:
错误C2664:'void RESTServer :: BindGET(RequestFunction)':无法从'std :: _ Binder <std :: _ Unforced,MessageContent(__cdecl communication :: CommunicationService ::*)(std :: string,MessageContent)转换参数1, communication :: CommunicationService*const,const std :: _ Ph <1>&>'to'RequestFunction'
之前,我的RequestFunction是这样的:
typedef std::function<void(std::string)> RequestFunction;
Run Code Online (Sandbox Code Playgroud)
它工作得很好.(当然,调整了所有签名方法).
我不明白导致错误的原因.
我想打一个方法convert,需要一个通用的函数bar(可以是std::function,lambda,functor,...),并将其转换为一个std::function<double(std::array<double, 3>)>.该功能bar可以是:
std::array<double, 3>作为一个参数并返回一个double.在这种情况下,convert写起来并不难:码:
template<typename F>
std::function<double(std::array<double, 3>)> convert (F& bar)
{
std::function<double(std::array<double,3>)> bar_converted = bar;
return bar_converted;
}
Run Code Online (Sandbox Code Playgroud)
doubles为参数并返回一个double.同样在这种情况下,convert写起来并不困难:码:
template<typename F>
std::function<double(std::array<double, 3>)> convert(F& bar)
{
std::function<double(std::array<double,3>)> bar_converted;
auto array_bar = [bar]( std::array<double, 3> x)->double{ return bar(x[0], x[1], x[2]); };
bar_converted = array_bar;
return bar_converted;
}
Run Code Online (Sandbox Code Playgroud)
问题是我不知道如何将这两种convert方法结合起来,或者这是否可能?
我试图了解 std::bind 和 std::function 是如何工作的。我无法编译以下代码:
#include <iostream>
#include <string>
#include <functional>
void function(int a, float b, std::string const &s)
{
std::cout << "printing function" << std::endl;
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << s << std::endl;
}
int main(int argc, char *argv[])
{
std::bind(&function, 10, 11.1, "hello")();
std::function<void(int, float, std::string const&)> fun = std::bind(&function, 10, std::placeholders::_1, std::placeholders::_2);
fun(0.2, "world");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨说:
main.cpp: In function 'int main(int, char**)':
main.cpp:16:69: error: conversion from 'std::_Bind_helper<false, void …Run Code Online (Sandbox Code Playgroud) 我想对(自定义)单链接列表中的元素运行一组操作。遍历链接列表并运行操作的代码很简单,但重复性很强,如果在各处复制/粘贴,可能会出错。性能和仔细的内存分配在我的程序中很重要,因此我想避免不必要的开销。
我想编写一个包装程序,以包含重复代码并封装将在链表的每个元素上进行的操作。由于操作中发生的功能各不相同,因此我需要捕获必须提供给操作的多个变量(在实际代码中),因此我着眼于using std::function。在此示例代码中完成的实际计算在这里没有意义。
#include <iostream>
#include <memory>
struct Foo
{
explicit Foo(int num) : variable(num) {}
int variable;
std::unique_ptr<Foo> next;
};
void doStuff(Foo& foo, std::function<void(Foo&)> operation)
{
Foo* fooPtr = &foo;
do
{
operation(*fooPtr);
} while (fooPtr->next && (fooPtr = fooPtr->next.get()));
}
int main(int argc, char** argv)
{
int val = 7;
Foo first(4);
first.next = std::make_unique<Foo>(5);
first.next->next = std::make_unique<Foo>(6);
#ifdef USE_FUNC
for (long i = 0; i < 100000000; ++i)
{
doStuff(first, [&](Foo& foo){ foo.variable += val + …Run Code Online (Sandbox Code Playgroud) 我一直在尝试捕获 std 函数 lambda 中的一些参数包参数,以便将函数保存在内存中以供将来使用。
然而,在某些情况下,如果这些捕获的参数中的任何值在捕获后被修改,则这些参数的未来使用不会达到预期的效果。
我想在我的 std 函数中存储参数包的不可变副本。
该代码将作为库实现,因此用户可以使用它来保存一些文本以供将来打印。这样我们就无法管理参数包中收到的参数。此示例必须对字符串、const char *、int、float 有效...
这是示例代码:代码链接
template <typename... Args>
void doPrint(std::ostream& out, const Args &... args)
{
using expander = int[];
(void)expander{0, (void(out << args), 0)...};
}
template<typename... Args>
void printArgs(const Args & ... args)
{
doPrint(std::cout, args...);
}
class PrintTest
{
private:
std::vector<std::function<void()>> myFunctions;
public:
template<typename... Args>
void saveText(const char * text, const Args & ... args)
{
std::function<void()> f = [this, text, args...]()
{
std::cout << text;
printArgs(args ...); …Run Code Online (Sandbox Code Playgroud) c++ ×10
std-function ×10
c++11 ×7
stdbind ×5
templates ×2
c++14 ×1
lambda ×1
performance ×1
type-traits ×1