我知道我可以std::function这样输入:
typedef std::function<void (const std::string&)> TextChangedHandler
Run Code Online (Sandbox Code Playgroud)
是否允许在typedef中指定参数名称,以使其更加自我记录?例如:
typedef std::function<void (const std::string& text)> TextChangedHandler
Run Code Online (Sandbox Code Playgroud)
我可以添加参数名称,它在Visual C++ 2010上编译得很好,但我想确保它是C++ 03/C++ 11标准所允许的.
鉴于以下内容,"功能"是什么类型?
#include <functional>
#include <vector>
template<class T>
class Foo
{
public:
template<typename P, typename Q, typename R, typename... Args>
void Attach(P (Q::*f)(Args...), R p)
{
auto function = [p, f](Args... args)
{
(*p.*f)(args...);
};
Listeners.push_back(function);
}
private:
std::vector<std::function<T>> Listeners;
};
class Bar
{
public:
int Handler(int x, int y, int z)
{
return 0;
}
};
int main(void)
{
auto foo = Foo<int(int, int, int)>();
auto bar = Bar();
foo.Attach(&Bar::Handler, &bar);
}
Run Code Online (Sandbox Code Playgroud)
对于某些上下文,我试图创建一个lambda来调用实例上的方法,将该lambda存储到一个集合中.我的push_back无法编译,出现以下错误:
xrefwrap(283):错误C2440:'return':无法从'void'转换为'int'
我最初使用std :: bind来创建一个我可以存储的std :: function.显然我可以用lambda(和可变参数模板,所以我不需要每个模板一个模板),但到目前为止,它击败了我.
今天我学习了完美的转发,我创建了这个代码示例
#include <utility>
#include <functional>
template<typename Function, typename... Args>
auto toStdFun(Function&& fun, Args&&...args)
{
using retType = decltype(fun(std::forward<Args>(args)...));
return std::function<retType(decltype(std::forward<Args>(args))...)>(fun);
}
int main()
{
toStdFun([] () {});
}
Run Code Online (Sandbox Code Playgroud)
然后,有人告诉我使用decltype(std::forward<Args>(args))...可以简单地表示Args&&...如下:
#include <utility>
#include <functional>
template<typename Function, typename... Args>
auto toStdFun(Function&& fun, Args&&...args)
{
using retType = decltype(fun(std::forward<Args>(args)...));
return std::function<retType(Args&&...)>(fun);
}
int main()
{
toStdFun([] () {});
}
Run Code Online (Sandbox Code Playgroud)
两个样本有什么区别?
请考虑以下代码.
#include <functional>
int main(void)
{
std::function<void()> f1;
if (f1) { /* ok */
...
}
bool b = f1; /* compile-error */
bool B = !f1; /* ok */
...
}
Run Code Online (Sandbox Code Playgroud)
std::function<>在某些情况下隐式转换为bool但不是全部转换为bool.将其分配给bool-variable不起作用,而操作的结果或在if()-statement中使用它是可以的.
为什么会这样?看来我们必须对它进行布尔运算,然后转换才有效.
我做的工作b = f1是什么 - 线是好的'双重爆炸:!!.它看起来像现代C++中的古董 - 代码.
编辑:这也编译:
bool b = f1 || f1; /* OK */
Run Code Online (Sandbox Code Playgroud) 我试图在不直接知道返回类型的情况下声明std函数.
显然,它将在编译时知道,但我找不到正确的方式来声明它.
最重要的是,我需要创建一个容器,其中包含来自此函数返回的值.
template <typename... Args>
class Sample
{
public:
Sample(Args... args, std::function</*unknown return type*/(Args...)> fnct) :
_inputBuff(std::forward_as_tuple(std::forward<Args>(args)...))
{ }
std::tuple<Args...> _inputBuff;
std::vector</*unknown return type*/> _resultBuff;
};
Run Code Online (Sandbox Code Playgroud)
有任何想法吗 ?
如果我通过引用将从std :: function派生的对象传递给另一个函数,则程序在运行时始终会因bad_function_call错误而崩溃.如下面的代码所示:
#include<functional>
#include<iostream>
class foo :public std::function<int(void)> {
public:
int operator()(){return 1;}
};
void bar(const std::function<int(void)>& f) {std::cout << f() << std::endl;}
int main(){
foo f;
bar(f);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果函数对象通过值传递,如下所示:
void bar(std::function<int(void)> f)
Run Code Online (Sandbox Code Playgroud)
程序运行正常.我在gcc,clang和visual studio上测试了这个程序,结果是一样的.导致这个bad_function_call的原因是什么?
我正在探索c ++ 17的新增内容.经过玩弄 std::variant,想用std::optional也用同样的例子.目前看到编译因以下错误而失败:
error: no viable conversion from returned value of type
'(lambda at ./html_parser.hpp:53:9)' to function return type 'Parser<char>' (aka
'std::__1::function<std::__1::optional<std::__1::pair<char, std::__1::basic_string<char> > >
(std::__1::basic_string<char>)>')
return [=](std::string& input) -> ParserResult<char> {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/acid/tools/include/c++/v1/functional:1627:5: note: candidate constructor not viable: no known conversion
from '(lambda at ./html_parser.hpp:53:9)' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
function(nullptr_t) _NOEXCEPT : __f_(0) {}
^
/home/acid/tools/include/c++/v1/functional:1628:5: note: candidate constructor not viable: no known conversion
from '(lambda at ./html_parser.hpp:53:9)' to 'const
std::__1::function<std::__1::optional<std::__1::pair<char, …Run Code Online (Sandbox Code Playgroud) 上一堂课
class Foo {
public:
std::shared_ptr<const Bar> quux(const std::string&, std::uint32_t);
}
Run Code Online (Sandbox Code Playgroud)
我可以声明一个std::function具有相同接口的:
std::function<std::shared_ptr<const Bar>(const std::string&, std::uint32_t)> baz = ...
Run Code Online (Sandbox Code Playgroud)
有没有一种压缩该声明的方法,使得to的模板参数std::function是从该方法的声明派生的,例如:
std::function<functype(X::quux)> baz = ...
Run Code Online (Sandbox Code Playgroud)
其中functype是虚C ++操作类似decltype。有没有办法做到这一点/ C ++是否具有这种能力?
我确实看到该方法的签名实际上稍有不同,因为它也需要对该this对象的引用/指针。我也可以派出这样的签名。
在我的一个项目中,我正在使用一个小的实用程序函数,该函数带有一个Message结构和一个lambda函数,用于修改此消息结构。
现在,我无意间通过了一个lambda,而没有必要的引用&。它可以完美地编译,但没有提供所需的输出。
对于我来说,应该有以下两种行为之一:
auto&,但是auto应该导致编译错误auto应该被解释为auto&。是否可以防止在丢失的情况下编译,&甚至更好地将其解释auto为auto&自动?
#include <iostream>
#include <functional>
#include <boost/variant.hpp>
struct Message {
int x;
int y;
};
void changeMessage(Message& m, const std::function<void(Message&)>& messageModifier) {
std::cout << "Message before:" << m.x << " " << m.y << "\n";
messageModifier(m);
std::cout << "Message after:" << m.x << " " << m.y << "\n";
}
int main(int, char**) {
{
std::function<void(int&)> f = [](int&) …Run Code Online (Sandbox Code Playgroud) 我正在使用a std::uniform_int_distribution生成素数(p)。我将分发对象放在一个匿名的命名空间中-对于成年人来说似乎是C ++的“静态链接” ...
namespace
{
// a more pedantic range: [2, 18446744073709551557]
std::uniform_int_distribution<uint64_t> p_dist {2};
std::mt19937 rng; // (sufficient IV states for uniqueness)
}
Run Code Online (Sandbox Code Playgroud)
请注意,在可移植代码允许的范围内,我尽可能彻底地播种了Mersenne Twister。不过,这对于这个问题并不是很重要。这只是为了确保读者可以正确使用随机工具:
std::seed_seq::result_type data[rng.state_size];
std::random_device rdev;
std::generate_n(data, rng.state_size, std::ref(rdev));
std::seed_seq rng_seed (data, data + rng.state_size);
rng.seed(rng_seed);
Run Code Online (Sandbox Code Playgroud)
这非常方便,因为我使用确定性u64_prime(p)函数,(7) bases可以确定是否(p)为质数:
uint64_t p;
while (!u64_prime(p = p_dist(rng)))
;
Run Code Online (Sandbox Code Playgroud)
现在,我创建一个std::function对象:
std::function<uint64_t()> zp_rng = std::bind(
decltype(p_dist){0, p - 1}, std::ref(rng));
Run Code Online (Sandbox Code Playgroud)
此函数:zp_rng()可以被调用以返回中的随机数Z(p)。也就是说,将分发对象用于:[0, p - 1] …