我知道以下代码无法编译。
void baz(int i) { }
void baz() { }
class Bar
{
std::function<void()> bazFn;
public:
Bar(std::function<void()> fun = baz) : bazFn(fun){}
};
int main(int argc, char **argv)
{
Bar b;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因为std::function据说不考虑重载决议,正如我在另一篇文章中读到的。
我不完全理解迫使这种解决方案的技术限制。
我在 cppreference 上阅读了翻译和模板的阶段,但我想不出任何我找不到反例的推理。向半个外行(C++ 的新手)解释一下,是什么以及在哪个翻译阶段导致上述无法编译?
std::function<>几乎任何可调用的东西都是一个有用的包装器,包括自由函数,lambda,仿函数,成员函数,结果std::bind.但是,在创建a时std::function<>,必须明确指定函数签名(取自此处)
struct Foo {
Foo(int num) : num_(num) {}
void print_add(int i) const { std::cout << num_+i << '\n'; }
int num_;
};
void print_num(int i)
{ std::cout << i << '\n'; }
struct PrintNum {
void operator()(int i) const
{ std::cout << i << '\n'; }
};
// store a free function
std::function<void(int)> f_display = print_num;
// store a lambda
std::function<void()> f_display_42 = []() { print_num(42); };
// store the result of …Run Code Online (Sandbox Code Playgroud) 我有一个重载函数,我想传递包裹在std :: function中.GCC4.6没有找到"匹配功能".虽然我在这里找到了一些问题,但答案并不像我希望的那样清晰.有人可以告诉我为什么下面的代码不能扣除正确的重载以及如何(优雅地)解决它?
int test(const std::string&) {
return 0;
}
int test(const std::string*) {
return 0;
}
int main() {
std::function<int(const std::string&)> func = test;
return func();
}
Run Code Online (Sandbox Code Playgroud) 我有一个关于如何正确使用新的C++ 11 std::function变量的问题.我已经看过几个搜索互联网的例子,但它们似乎并没有涵盖我正在考虑的用例.拿这个最小的例子,其中函数fdiff是定义的有限前向差分算法的实现numerical.hxx(这不是问题,我只是想给出一个上下文的原因,为什么我想要采用任意函数并传递它) .
#include <functional>
#include <iostream>
#include <cmath>
#include "numerical.hxx"
int main()
{
double start = 0.785398163;
double step = 0.1;
int order = 2;
std::function<double(double)> f_sin = std::sin;
std::cout << fdiff(start, step, order, f_sin) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
试图编译上面的程序给我错误(在clang ++中)
test.cpp:11:32: error: no viable conversion from '<overloaded function type>' to
'std::function<double (double)>'
std::function<double(double)> f_sin = std::sin;
^ ~~~~~~~~
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/functional:2048:7: note:
candidate constructor not viable: no overload of 'sin' matching
'nullptr_t' for …Run Code Online (Sandbox Code Playgroud) 我有一个目前锁定在Visual Studio 2015中的项目.但是,我想编写符合标准的代码.
我想使用std::filesystem它,但直到C++ - 17才进入标准.幸运的是,几乎所有东西都可用,就在std::experimental::filesystem::v1命名空间中.我不喜欢一揽子using指令; 我更喜欢将事情做好,以明确事情的来源.所以我不打算在全球范围内using发表声明.需要一些魔法才能说服编译器按我的意愿行事.
这是我的第一次尝试:
#include <filesystem>
#if defined(_MSC_VER) && _MSC_VER <= 1900 // VS 2015
namespace std {
namespace filesystem {
using path = std::experimental::filesystem::v1::path;
}
}
#endif
Run Code Online (Sandbox Code Playgroud)
这很好用,std::filesystem::path现在可以访问.我测试了创建和使用path对象,它的工作原理.
随着我前进,我知道我将需要更多的东西.我想知道是否有办法引入整个事情:
namespace std {
namespace filesystem {
using std::experimental::filesystem::v1;
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎是倒退了一步.似乎没有任何东西可见.事后来看,我认为这是有道理的,因为using语句的范围以下一行的右括号结束.
接下来,我想得到一个directory_entry.同样的技术似乎有效
namespace std {
namespace filesystem {
using directory_entry = std::experimental::filesystem::v1::directory_entry;
}
}
Run Code Online (Sandbox Code Playgroud)
再次,编译器似乎很高兴.
现在,我想用std::directory::create_directories.但是,这是一个函数,而不是一个类,所以相同的技术将无法工作.
我认为这std::function …
这个问题对我来说似乎有点愚蠢,但我找不到任何类似的问题,对不起,这很琐碎
假设我们有一个结构:
struct C {
static void f(int i) { std::cerr << (i + 15) << "\n"; }
static void f(std::string s) { std::cerr << (s + "15") << "\n"; }
};
Run Code Online (Sandbox Code Playgroud)
现在在其他地方:
std::function<void(int)> f1 = C::f; // this does not compile
void (*f2)(std::string s) = C::f; // this compiles just fine
Run Code Online (Sandbox Code Playgroud)
我得到的错误是
错误:请求从“”转换为非标量类型“ std :: function”
在这种情况下有什么方法可以使用std :: function吗?我想念什么?
谢谢