我想创建一个C宏,它创建一个名称基于行号的函数.我以为我可以做类似的事情(真正的函数会在括号内有声明):
#define UNIQUE static void Unique_##__LINE__(void) {}
Run Code Online (Sandbox Code Playgroud)
我希望将扩展到以下内容:
static void Unique_23(void) {}
Run Code Online (Sandbox Code Playgroud)
这不起作用.使用令牌连接,定位宏按字面处理,最终扩展为:
static void Unique___LINE__(void) {}
Run Code Online (Sandbox Code Playgroud)
这可能吗?
(是的,无论这看起来多么无用,我都有一个真正的理由要这样做).
我在许多Python程序中都使用了yield,在很多情况下它确实清除了代码.我在博客上写了这篇文章,这是我网站的热门网页之一.
C#还提供了收益 - 它通过调用者端的状态保持来实现,通过自动生成的类来完成,该类保持状态,函数的局部变量等.
我目前正在阅读有关C++ 0x及其添加的内容; 在阅读有关C++ 0x中lambda的实现时,我发现它也是通过自动生成的类完成的,配备了存储lambda代码的operator().我心中形成了一个自然的问题:他们是为lambdas做过的,他们为什么不考虑支持"收益"呢?
当然,他们可以看到合作例程的价值......所以我只能猜测他们认为基于宏的实现(例如Simon Tatham的)是一个充分的替代品.然而,它们不是出于多种原因:被调用者保持状态,非重入状态,基于宏观(仅此一点是足够的理由)等.
编辑: yield不依赖于垃圾收集,线程或光纤.您可以阅读Simon的文章,看看我在谈论编译器进行简单的转换,例如:
int fibonacci() {
int a = 0, b = 1;
while (true) {
yield a;
int c = a + b;
a = b;
b = c;
}
}
Run Code Online (Sandbox Code Playgroud)
成:
struct GeneratedFibonacci {
int state;
int a, b;
GeneratedFibonacci() : state (0), a (0), b (1) {}
int operator()() {
switch (state) {
case 0:
state = 1;
while (true) { …Run Code Online (Sandbox Code Playgroud) 我必须更新连接到串行端口的设备上的固件和设置.由于这是通过一系列命令完成的,因此我发送命令并等待直到我收到答案.在answere(多行)里面,我搜索一个字符串,指示操作是否成功完成.
Serial->write(“boot”, 1000);
Serial->waitForKeyword(“boot successful”);
Serial->sendFile(“image.dat”);
…
Run Code Online (Sandbox Code Playgroud)
所以我为这个阻塞读/写方法创建了一个新的Thread.在线程内部我使用了waitForX()函数.如果我调用watiForKeyword(),它将调用readLines()直到它检测到关键字或超时
bool waitForKeyword(const QString &keyword)
{
QString str;
// read all lines
while(serial->readLines(10000))
{
// check each line
while((str = serial->getLine()) != "")
{
// found!
if(str.contains(keyword))
return true;
}
}
// timeout
return false;
}
Run Code Online (Sandbox Code Playgroud)
readLines()读取所有可用的东西并将其分成行,每行放在一个QStringList中,并获取一个我调用getLine()的字符串,它返回列表中的第一个字符串并删除它.
bool SerialPort::readLines(int waitTimeout)
{
if(!waitForReadyRead(waitTimeout))
{
qDebug() << "Timeout reading" << endl;
return false;
}
QByteArray data = readAll();
while (waitForReadyRead(100))
data += readAll();
char* begin = data.data();
char* ptr = strstr(data, "\r\n");
while(ptr != NULL) …Run Code Online (Sandbox Code Playgroud) 我是多线程编程的新手.我用Qt编写了这个简单的多线程程序.但是当我运行这个程序时它会冻结我的GUI,当我点击我的寡妇时,它会回应你的程序没有响应.这是我的widget类.我的线程开始计算一个整数,当这个数字可以被1000分割时发出它.在我的小部件中,我只是用信号槽机制捕获这个数字,并在标签和进度条中显示它.
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
MyThread *th = new MyThread;
connect( th, SIGNAL(num(int)), this, SLOT(setNum(int)));
th->start();
}
void Widget::setNum(int n)
{
ui->label->setNum( n);
ui->progressBar->setValue(n%101);
}
Run Code Online (Sandbox Code Playgroud)
这是我的线程run()函数:
void MyThread::run()
{
for( int i = 0; i < 10000000; i++){
if( i % 1000 == 0)
emit num(i);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
我的Qt应用程序与串行设备通信,偶尔必须等待此设备发送一个字节.为了实现这一点,我创建了一个新的eventloop,一旦串行缓冲区中有可用信息就会退出:
unsigned char MyClass::waitForDevice(int timeout)
{
QEventLoop wait;
connect(d_serial, SIGNAL(readyRead()), &wait, SLOT(quit()));
if (timeout > 0)
QTimer::singleShot(timeout, &wait, SLOT(quit()));
wait.exec();
return static_cast<unsigned char>(d_serial->read(1)[0]);
}
Run Code Online (Sandbox Code Playgroud)
现在的问题是,当应用程序在等待时,即在eventloop运行时,我需要能够在GUI中按下按钮时与串行设备进行通信.天真地,我尝试将信号连接到执行此操作的插槽,但我发现插槽仅在 eventloop终止后执行.
我试着,没有任何运气,有一个单独的QThread运行调用qApp->processEvents()无限循环,当eventloop终止时终止.这没用,我不太清楚为什么不呢.解决这个问题的规范方法是什么?