问题:以下代码非常具有表现力和简洁性,如果不一定快,则不是因为它不能编译.
它无法编译,因为您无法将std :: function实例与operator ==()进行比较.而std :: find()试图做到这一点.
当然,我可以采用完全不同的实现方式,但是我很顽固,因为我喜欢下面的代码,我正在寻找"尽可能接近"的东西.
谁可以为我提供一个相当重写的代码,下面的代码也做同样的事情?
#include <functional>
#include <vector>
typedef std::function<bool(int)> Tester_t;
typedef std::vector<Tester_t> TesterSet_t;
bool Test(TesterSet_t &candidates, int foo)
{
TesterSet_t dropouts;
for( auto& tester : candidates )
{
if(!tester(foo))
{
droputs.push_back(tester);
}
}
while(!dropouts.empty())
{
// The following line is not compiling because std::function has no operator==()
TesterSet_t::iterator culprit =
std::find( candidates.begin(), candidates.end(), dropouts.back() );
candidates.erase(culprit);
dropouts.pop_back();
}
return !candidates.empty();
}
Run Code Online (Sandbox Code Playgroud) 好吧,也许它并不那么令人惊讶.Stackoverflow在这一点上有很多问题和贡献.只有他们并不完全是这一点.
这里是C++标准的摘录(事实上是c ++ 14草案,但我认为这段经文在当前的C++ 11标准中是相同的):
运算符函数应该是非静态成员函数,或者是非成员函数,其至少具有一个类型为类的参数,对类的引用,枚举或对枚举的引用.无法更改运算符的优先级,分组或操作数.通过定义实现这些运算符的运算符函数,可以针对特定类和枚举类型更改为每种类型预定义的operator =,(一元)&和(逗号)的含义.运算符函数的继承方式与其他基类函数的继承方式相同.
因此,根据我的理解,将1个类类型和一个非类型类型作为operator >>(,)的参数是完全合法的.该标准没有说"第一个"或"第二个"参数.其中只有"一个"必须是类类型.
这里有一个令我惊讶的代码片段:
int operator>> ( int v, std::function<int(int)> transformer )
{
int v1 = transformer(v);
DGS::CLogger::GetLogger()->Log<int>(&IntFormatter, v1 );
return v1;
}
static int DoItLoggedAndCompact( int value )
{
int x = operator>>( operator>>(value, DoIt) , AnotherIntCalculation ); // compiles and works!
return x;
// The following line produces (with clang++):
// error: invalid operands to binary expression ('int' and 'int (*)(int)')
// return value >> DoIt >> AnotherIntCalculation; :
}
Run Code Online (Sandbox Code Playgroud)
请注意,"函数指针不是类类型",而作为正确的语句,并不是一个全面的答案.正如您在重写代码中看到的那样,int …
这个问题以一些代码开始,只是因为我认为更容易看到我所追求的内容:
/*static*/
void
Url::Split
(std::list<std::string> & url
, const std::string& stringUrl
)
{
std::string collector;
collector.reserve(stringUrl.length());
for (auto c : stringUrl)
{
if (PathSeparator == c)
{
url.push_back(collector);
collector.clear(); // Sabotages my optimization with reserve() above!
}
else
{
collector.push_back(c);
}
}
url.push_back(collector);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,该collector.reserve(stringUrl.length());行应该减少下面循环期间执行的堆操作量。毕竟,每个子字符串不能比整个 url 长,因此像我一样保留足够的容量看起来是个好主意。
但是,一旦子字符串完成并将其添加到 url 部分列表中,我需要以某种方式将字符串重置为长度 0。简短的“查看定义”检查表明,至少在我的平台上,保留的缓冲区将被释放,这样,我的 Reserve() 调用的目的就会受到损害。
_Eos(0)在内部它会在清除的情况下调用一些。
我也可以完成相同的任务,collector.resize(0)但查看定义显示它也在内部调用_Eos(newsize),因此行为与调用 的情况相同clear()。
现在的问题是,是否有一种可移植的方法来建立预期的优化,以及哪个std::string函数可以帮助我实现这一点。
我当然可以写,collector[0] = '\0';但这对我来说看起来很不合适。
旁注:虽然我发现了类似的问题,但我认为这不是其中任何一个的重复。
提前致谢。
[<ReflectedDefinition>]
module Foo =
let x = 5
let y () = 6
let z a = a
Run Code Online (Sandbox Code Playgroud)
我试图找出如何在这种情况下获得AST的方法几次,并且一直失败。是时候在这里问问题了。
到目前为止,我认为模块将被映射到内部具有静态成员的类,因此,它应等效于:
[<ReflectedDefinition>]
type Foo =
static member x = 5
static member y () = 6
static member z a = a
let bar_members =
typeof<Bar>.GetMethods()
|> Array.filter (fun mi -> match mi with | MethodWithReflectedDefinition x -> true | _ -> false)
|> Array.map (fun m -> sprintf "%s: %A" (m.Name) (Expr.TryGetReflectedDefinition(m :> MethodBase) ) )
Run Code Online (Sandbox Code Playgroud)
在后一种情况下,我可以使用typeof<Foo>.GetMembers()(或GetMethods() …
在旧版本的 mio 文档中,我找到 mio::channel,它似乎用于创建EventedFd可以注册的通道实现Poll。我还在 reddit 上看到这已被更改为有利于其他内容,但我不知道注册频道的新方式是什么。
std::sync::mpsc迄今为止,使用 mio 等待频道(或其他内容)的当前方式是什么?我在谷歌上能找到的只是旧版本 mio 文档的链接。谢谢 !
当我遇到同样的问题时,我希望可以提供一些代码以使问题更容易理解:
use std::io;
use std::net::*; //{TcpListener,TcpStream,IpAddr,Ipv4Addr,SocketAddr};
use std::thread::*;
use std::sync::mpsc::*; //{Receiver,SyncSender,Sender,channel,sync_channel};
fn poll_quit( rx : &Receiver::<u8> ) -> bool {
match rx.try_recv() {
Ok(_) => true,
Err(TryRecvError::Empty) => false,
Err(TryRecvError::Disconnected) => true
}
}
fn guard_external_tcp_port( rx : Receiver::<u8>) -> () {
let listener = TcpListener::bind("127.0.0.1:8384").expect("tcp guard - bind failed!");
listener.set_nonblocking(true).expect("cannot set tcp listener to nonblocking!");
while false == poll_quit(&rx) {
match listener.accept() …Run Code Online (Sandbox Code Playgroud) 在阅读了String, Text, Text.Lazy, ByteString, ByteString.LazyHaskell中关于字符串的所有5个()常用类型之后,我宁愿精疲力尽:
我需要的是一个不可变的String类型(我从文件中读取一次,从不更改),具有快速索引(O(1)),并且可以由代码点使用,而不是由潜在的不完整字节使用,形成一个代码点。
我可以忍受一个Data.ByteString.UTF32,实际上,就像那个表示形式一样,我不需要再对多字节编码进行小心了。
我是否需要为自己编写这样的模块,或者(是否有机会)别人是否得出了相同的结论并且已经做到了?
我计划使用FParsec作为我的一个更大项目的原型.所以我决定通过下面列出的测试程序获得我对该库的第一次体验.但似乎通过使用fparsec"choice"函数组合我的基本解析器(似乎工作)会产生意外行为.
基本上,目标是所有这些简单的计算器解析器代码总是返回数字或子表达式的乘积之和.子表达式依次具有与整个表达式相同的结构.
正如我从"选择"的文档中所理解的那样,在"选择"的解析器列表中指定的从左到右尝试的替代方案.我明白如果列表中的进一步遗留的解析器失败但消耗了输入,则不会尝试后续的解析器.
然而,现在似乎还有比我现在理解的更多,就像我上面所说的那样,代码应该有效.但它不起作用.
如果有人能向我解释a)出了什么问题以及为什么和b)如何解决它,我将不胜感激.
在我的主项目中,我计划从一些输入中计算解析器,因此我需要准确理解如何以可靠的方式组合解析器而没有意外.
(*
SimpleAOSCalculator
Should implement the following grammar:
SimpleAOSCalculator := SUM
SUM := SUMMAND [ '+' SUMMAND ]*
SUMMAND := PRODUCT | SUBEXPR
PRODUCT := FACTOR [ '*' FACTOR ]*
FACTOR := NUMBER | SUBEXPR
SUBEXPR := '(' SUM ')'
NUMBER := pfloat
*)
// NOTE: If you try this in fsi, you have to change the 2 lines below to point to the spot you have your fparsec dlls stored at.
#r @"C:\hgprojects\fparsec\Build\VS11\bin\Debug\FParsecCS.dll"
#r …Run Code Online (Sandbox Code Playgroud) 在下面的代码片段中,我看不出为什么我必须编写f和g函数的方式foo以及为什么它不能像函数bar尝试那样工作.
let f a b = a,b
let g (a : 'a) (b : 'a) = a
let (>!) f1 f2 =
fun a b ->
let (x,y) = f1 a b
f2 x y
let foo = fun a b -> (f >! g) a b
let bar = f >! g
Run Code Online (Sandbox Code Playgroud)
任何人都可以向我解释,为什么bar不工作?鉴于它foo也具有通用类型,对我来说没有任何意义.
STM (State# RealWorld -> (#State# RealWorld, a#))
Run Code Online (Sandbox Code Playgroud)
#没有显示在Haskell运算符列表中,谷歌也没有产生任何有用的东西.Ghci:>:t (#)states:变量不在范围内.
那个角色做了什么?为什么在上面的代码中使用它(来自STM)?
今天就找到了编程语言"pony"......并开始玩它.
我的代码应该做一些简单的生产者消费者的事情.正如语言文档所声称的,该语言确保没有数据竞争.
这里,main向生产者发送10条消息,生产者又向消费者发送10条消息.消费者递增计数器状态变量.然后,main向消费者发送消息,消费者又向main发送消息以显示当前值.如果所有消息都按顺序排列,则预期值将为9(或10).打印结果虽然是0.
因为这是我用语言玩的第一个小时,当然我可能搞砸了别的东西.
谁可以解释我的错误?
use "collections"
actor Consumer
var _received : I32
new create() =>
_received = 0
be tick() =>
_received = _received + 1
be query(main : Main) =>
main.status(_received)
actor Producer
var _consumer : Consumer
new create(consumer' : Consumer) =>
_consumer = consumer'
be produceOne () =>
_consumer.tick()
actor Main
var _env : Env
new create(env: Env) =>
_env = env
let c : Consumer = Consumer.create()
let p = Producer.create(c)
for i in Range[I32](0,10) do …Run Code Online (Sandbox Code Playgroud)