很确定我知道这个问题的答案(思考不),但是可以在API(跨模块边界)中安全地接受/返回std :: function by value吗?
我在想'不',因为我认为没有任何保证,一个供应商的std :: function实现与另一个供应商兼容.是这样的吗?
如果我怀疑答案是否定的,你们怎么处理这类事情呢?我可能不得不求助于实现我自己或者只是避免像std :: function这样的东西(例如:使用函数指针或函数).:-(我发现自己在很多情况下都是这样做的(重新发明了许多标准C++库,当然甚至令人遗憾的是,我们自己的STL兼容矢量类型支持范围ctor和fill ctor,自定义分配器等当然不是很有趣,我怀疑它和标准实现一样好,只是因为有人可能会动态链接到一个库,比如MSVC 2010从mingw编写的二进制文件实现std :: function,例如
当然,替代方案是在我们的API中根本不使用这些类型的C++特性并使用C接口,但由于我们使用API作为中心API,因此这将花费相当沉重的代价.内部和第三方发展.
是否可以std::function使用模板参数定义的类型的构造函数构造?
例如:
template <typename T>
bool registerType()
{
const std::function<T()> func = &T::T; //I know this doesn't work
//...
}
Run Code Online (Sandbox Code Playgroud) 由于std::function可以保存成员函数,因此它必须在某处存储指向对象实例的指针.
如何this从std::function包含成员函数的指针中获取指针?
给定具有捕获变量的lambda函数,例如
[&x] (int y) { x += y; }
Run Code Online (Sandbox Code Playgroud)
int x当我将这个lambda传递给类型的变量时,上下文(这里是对词法上下文中任何地方定义的某个变量的引用)在哪里std::function<void(int)>?
我知道像std::vector或的动态大小存储std::string,但它们都存储固定类型的值(当然,模板参数一旦知道).但是在lambdas的情况下,这样的存储应该能够存储任何类型的值,在客户端代码的编译时已知,它将lambda分配给a std::function,但在传递函数时不知道.
我的意思是,当我们修复具体类型时std::function,我们修复了函数签名,但不修复捕获的变量/引用的类型.在场景后面必须有一些动态大小和动态类型存储.显然,这不可能是例如std::tuple因为这需要在实例化时知道类型,std::function但它们不是.所以我想知道它是如何实现的(例如在g ++中,但可能存在与此问题无关的编译器答案).
我需要创建一个模板化的类,该类可以容纳指向类型元素的指针T,然后对它们执行功能。这些函数将来自不同的地方,因此我需要一个容器来存储它们,以便以后可以调用它们。我决定使用std::unordered_set,因为它被实现为哈希表,因此提供了速度并限制了重复。我写了一个完整的类,但是由于没有为我定义的哈希函数std::function接受类型指针T并返回而无法编译void。为我使用的每种类型使用struct hash<std::function<void(MyCustomType*)>>(并且也重载()运算符)来指定它很容易,但是实际上如何对函数进行哈希处理呢?
这是我班上的简短摘录,其中包含相关的成员和方法:
template <typename T>
class Master {
private:
std::unordered_set<std::function<void(T*)>> functions;
protected:
registerFunction(std::function<void(T*)> function) {
this->functions.insert(function);
}
unregisterFunction(std::function<void(T*)> function) {
this->functions.erase(function);
}
};
Run Code Online (Sandbox Code Playgroud)
我并不完全愿意使用std::unordered_set,但是它似乎提供了使此代码段(以及我的代码的其余部分)正常运行所需的一切。
我在想这个错误的方式吗?散列a完全不可能std::function吗?
考虑以下示例:
#include <iostream>
#include <functional>
using namespace std;
void f(int x,int y) {}
// void f(int x) {} // if this line is uncommented, code does not compile.
int main() {
auto functor = std::bind(&f,1,placeholders::_1);
cout << "works!" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它可以按原样(https://ideone.com/fork/2SywE2)进行编译和运行,但是取消注释注释行会导致编译器错误:
prog.cpp:在函数'int main()'中:prog.cpp:10:48:错误:没有匹配的函数调用'bind(,int,const std :: _ Placeholder <1>&)'auto functor = std :: bind(&f,1,placeholders :: _ 1); ^在prog.cpp中包含的文件中:2:0:/ usr / include / c ++ / 5 / functional:1462:5:注意:候选:模板类型名称std :: _ Bind_helper :: value,_Func,_BoundArgs ...>: :type std …
我目前正尝试使用功能模板std::bind创建一个std::function<void()>
template<class Iterator>
void printRange(Iterator first, Iterator last) {
std::copy(first, last, std::ostream_iterator<typename Iterator::value_type>(std::cout, " "));
std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
从概念上讲,我想要的是
int main() {
std::vector<int> v{1, 2, 3};
auto f0 = std::bind(printRange, v.begin(), v.end()); // won't compile, of course
f0();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道这不能编译,因此我必须实例化函数模板才能真正使用它。例如,以下替代方法将起作用:
auto f1 = std::bind(printRange<std::vector<int>::const_iterator>, v.begin(), v.end());
auto f2 = std::bind(printRange<decltype(v.begin())>, v.begin(), v.end());
auto f3 = [&v]() { printRange(v.begin(), v.end()); };
Run Code Online (Sandbox Code Playgroud)
我已经创建了一个便利功能
template<class Iterator>
std::function<void()> makePrintRangeFunction(Iterator first, Iterator last) {
return std::bind(printRange<Iterator>, first, last);
} …Run Code Online (Sandbox Code Playgroud) 需要在类中具有一个具有默认功能的函数变量,并且它的功能可以被覆盖.示例我喜欢/想要做什么(不幸的是失败):
#include <iostream>
#include <functional>
using namespace std;
class Base
{
public:
std::function<bool(void)> myFunc(){
cout << "by default message this out and return true" << endl;
return true;}
};
bool myAnotherFunc()
{
cout << "Another functionality and returning false" << endl;
return false;
}
int main()
{
Base b1;
b1.myFunc(); // Calls myFunc() with default functionality
Base b2;
b2.myFunc = myAnotherFunc;
b2.myFunc(); // Calls myFunc() with myAnotherFunc functionality
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道,这段代码不能编译.任何人都可以帮助解决这个问题,或推荐一些东西 如果有另一种方法来实现这个逻辑,则不需要是std :: function.也许应该使用lambda?!
我只是碰到了一些奇怪的东西.我想知道这是不是一个错误,如果不是,我希望有人可以解释这个问题.
我的问题是,当我创建一个std::function带有默认参数的模板化函数时,我只能创建一个这个函数的模板实例,否则会出错.
请考虑以下代码:
#include <functional>
template<bool B>
void wut(std::function<void()> f = []() {})
{
f();
}
int main() {
wut<false>(); // works
wut<false>(); // still works
wut<true>(); // error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译此代码时,我收到以下错误:
{standard input}: Assembler messages:
{standard input}:28: Error: symbol `_ZNSt14_Function_base13_Base_managerIUlvE_E10_M_managerERSt9_Any_dataRKS3_St18_Manager_operation' is already defined
{standard input}:127: Error: symbol `_ZNSt17_Function_handlerIFbvEUlvE_E9_M_invokeERKSt9_Any_data' is already defined
Run Code Online (Sandbox Code Playgroud) #include <functional>
#include <iostream>
template<typename T>
void test( std::function< void ( const T& ) > f )
{
T val {};
f( val );
std::cout << "std::function" << std::endl;
}
template<typename T>
void test( void(*f) ( const T& ) )
{
T val {};
f( val );
std::cout << "function pointer" << std::endl;
}
int main()
{
auto capturing_var { 0 };
// Works because implicit conversion to function pointer isn't applied when lambda is capturing
test< int >( [ …Run Code Online (Sandbox Code Playgroud)