我知道它们可以一起使用,但我想知道是否有可能在程序的Qt部分(小部件等)中用Boost.Signal替换Qt的信号和插槽机制.
有人试过吗?任何陷阱?
假设我没有使用任何其他MOC功能并用boost.signal替换信号/插槽,是否可以完全不使用moc?
我的程序中有几个函数看起来像这样:
void foo(int x, int y)
Run Code Online (Sandbox Code Playgroud)
现在我希望我的程序采用如下字符串:
foo(3, 5)
Run Code Online (Sandbox Code Playgroud)
并执行相应的功能.实现这一目标最简单的方法是什么?
当我直截了当地说,我的意思是合理的可扩展性和优雅,但编码不应该花太长时间.
编辑:
虽然使用真正的脚本语言当然可以解决我的问题,但我仍然想知道是否有一种快速的方法可以在纯C++中实现它.
有没有什么方法可以组合谓词?
让我们说我有这样的事情:
class MatchBeginning : public binary_function<CStdString, CStdString, bool>
{ public:
bool operator()(const CStdString &inputOne, const CStdString &inputTwo) const
{ return inputOne.substr(0, inputTwo.length()).compare(inputTwo) == 0; }
};
int main(int argc, char* argv[])
{
CStdString myString("foo -b ar -t az");
vector<CStdString> tokens;
// splits the string every time it encounters a "-"
split(myString, tokens, "-", true, true);
vector<CStdString>::iterator searchResult = find_if(tokens.begin(), tokens.end(), not1(bind2nd(MatchBeginning(), "-")));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这有效,但现在我想做一些事情:
searchResult = find_if(tokens.begin(), tokens.end(), bind2nd(MatchBeginning(), "-b") || not1(bind2nd(MatchBeginning(), "-")));
Run Code Online (Sandbox Code Playgroud)
所以我想找到第一个以"-b"开头的字符串或第一个不以" - "开头的字符串.但是,这给了我一个错误(二进制'||'未定义).
有没有办法做到这一点?
我通过网络传输了一个字符/字节数组.它包含标题和一些数据.我想将标题映射到结构上.这是一个例子:
#pragma pack(1)
struct Header
{
unsigned short bodyLength;
int msgID;
unsigned short someOtherValue;
unsigned short protocolVersion;
};
int main()
{
boost::array<char, 128> msgBuffer;
Header header;
for(int x = 0; x < sizeof(Header); x++)
msgBuffer[x] = 0x01; // assign some values
memcpy(&header, msgBuffer.data(), sizeof(Header));
system("PAUSE");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
假设结构永远不包含任何可变长度字段,这总是有效吗?是否有平台独立/惯用的方式来做到这一点?
注意:
我在互联网上看到了很多允许你序列化/反序列化的库,但我得到的印象是,如果以前用同一个库序列化它们,它们只能反序列化.好吧,我无法控制传输的格式.我肯定会得到一个byte/char数组,其中所有值都是相互跟随的.
我有一个char(即字节)缓冲区,我通过网络发送.在将来的某个时候,我可能想要将缓冲区切换为不同的类型,如unsigned char或short.我一直在考虑做这样的事情:
typedef char bufferElementType;
Run Code Online (Sandbox Code Playgroud)
每当我用缓冲元素做任何事情时,我都会声明它bufferElementType而不是char.这样我可以通过改变这个typedef切换到另一种类型(当然它不会那么简单,但它至少很容易识别需要修改的地方...... bufferElementType附近会有一个).
这是typedef的有效/好用吗?难道不值得吗?这会在将来的某个时候让我头疼吗?会不会让维护程序员讨厌我?
我已经阅读了何时应该在C++中使用Typedef,但没有人真正涵盖这一点.
我一直在寻找一个示例来展示如何在 C++ 中实现约束(或一个可以让我轻松完成此操作的 boost 库),但运气不佳。我能想到的最好的办法是:
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
template<typename T>
class constrained
{
public:
constrained(boost::function<bool (T)> constraint, T defaultValue, T value = defaultValue)
{
ASSERT(constraint(defaultValue));
ASSERT(constraint(value));
this->value = value;
this->defaultValue = defaultValue;
this->constraint = constraint;
}
void operator=(const T &assignedValue)
{
if(constraint(assignedValue))
value = assignedValue;
}
private:
T value;
T defaultValue;
boost::function<bool (T)> constraint;
};
int main(int argc, char* argv[])
{
constrained<int> foo(boost::lambda::_1 > 0 && boost::lambda::_1 < 100, 5, 10);
foo = 20; // works
foo = -20; …Run Code Online (Sandbox Code Playgroud) 我有一个程序(除此之外)有一个命令行界面,让用户输入字符串,然后通过网络发送.问题是我不确定如何将在GUI内部生成的事件连接到网络接口.假设我的GUI类层次结构如下所示:
GUI - > MainWindow - > CommandLineInterface - > EntryField
每个GUI对象都包含一些其他GUI对象,一切都是私有的.现在,entryField对象生成一个已输入消息的事件/信号.目前我正在将信号传递给类层次结构,因此CLI类看起来像这样:
public:
sig::csignal<void, string> msgEntered;
Run Code Online (Sandbox Code Playgroud)
而在c'tor:
entryField.msgEntered.connect(sigc::mem_fun(this, &CLI::passUp));
Run Code Online (Sandbox Code Playgroud)
passUp函数只是为拥有类(MainWindow)再次发出信号才能连接,直到我最终可以在主循环中执行此操作:
gui.msgEntered.connect(sigc::mem_fun(networkInterface, &NetworkInterface::sendMSG));
Run Code Online (Sandbox Code Playgroud)
现在这似乎是一个非常糟糕的解决方案.每次我向GUI添加内容时,我都必须通过类层次结构将其连接起来.我确实看到了几种方法.我可以将所有对象公开,这将允许我在主循环中执行此操作:
gui.mainWindow.cli.entryField.msgEntered.connect(sigc::mem_fun(networkInterface, &NetworkInterface::sendMSG));
Run Code Online (Sandbox Code Playgroud)
但这违背了封装的想法.我还可以在整个GUI上传递对网络接口的引用,但我希望尽可能保持GUI代码的分离.
感觉我在这里缺少必要的东西.有干净的方法吗?
注意:我正在使用GTK +/gtkmm/LibSigC++,但我没有标记它,因为我和Qt有同样的问题.这是一个普遍的问题.
我得到一个指向基类的指针(实际上是指向某个派生类的指针).然后我想在派生类上调用一个函数,但我不知道它是哪一个.
class Base
{
};
class DerivedOne : public Base
{
public:
void functionA()
{ int x = 0; }
};
class DerivedTwo : public Base
{
public:
void functionA()
{ int x = 0; }
};
int main()
{
Base* derivedTwoPtr = new DerivedTwo();
reinterpret_cast<DerivedOne*>(derivedTwoPtr)->functionA();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是我想要的,但我不得不说它看起来很狡猾.它是否定义了行为?如果没有,是否有合法的方法来动态解决这个问题?