gcc抱怨这个:
#include <stdio.h>
static const int YY = 1024;
extern int main(int argc, char*argv[])
{
static char x[YY];
}
Run Code Online (Sandbox Code Playgroud)
$ gcc -c test1.c test1.c:在函数main':
test1.c:5: error: storage size ofx'中不是常量test1.c:5:错误:变量`x'的大小太大
从x的定义中删除"静态",一切都很好.
我不清楚这里发生了什么:肯定YY 是不变的?
我一直认为"静态const"方法比"#define"更可取.在这种情况下有没有办法使用"静态const"?
我正在考虑关于const和非const类方法的这个问题.首选答案取自Scott Meyers的Effective C++,其中非const方法是根据const方法实现的.
进一步扩展,如果方法返回迭代器而不是引用,如何减少代码重复?修改链接问题中的示例:
class X
{
std::vector<Z> vecZ;
public:
std::vector<Z>::iterator Z(size_t index)
{
// ...
}
std::vector<Z>::const_iterator Z(size_t index) const
{
// ...
}
};
Run Code Online (Sandbox Code Playgroud)
我不能在const方法方面实现非const方法,因为不使用distance()/ advance()技术就无法直接从const_iterator转换为迭代器.
在这个例子中,因为我们使用std :: vector作为容器,所以实际上可以从const_iterator转换为迭代器,因为它们很可能被实现为指针.我不想依赖于此.有更通用的解决方案吗?
我有一个makefile,它通常创建目录:
$(Release_target_OBJDIR)/%.o: %.cpp
mkdir -p $(dir $@)
$(COMPILE.cpp) $< $(CFLAGS) $(INCLUDES) -o $@
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我在scratchbox2下运行它时,mkdir -p命令总是无声地失败.
我尝试了以下无效的kludge:
$(Release_target_OBJDIR)/%.o: %.cpp
mkdir $(dir $(dir $(dir $@)))
mkdir $(dir $(dir $@))
mkdir $(dir $@)
$(COMPILE.cpp) $< $(CFLAGS) $(INCLUDES) -o $@
Run Code Online (Sandbox Code Playgroud)
这输出:
mkdir -p /home/foo/projects/htc/arm/obj/cbar/release/
mkdir -p /home/foo/projects/htc/arm/obj/cbar/release/
mkdir -p /home/foo/projects/htc/arm/obj/cbar/release/
Run Code Online (Sandbox Code Playgroud)
...尾部斜杠阻止dir函数以我想要的方式剥离最后一个目录.
如果没有编写脚本或小型C应用程序来复制"-p"功能,是否有人有任何想法在makefile中创建子目录?
如果没有-p选项,当makefile尝试创建已存在的目录时,mkdir将给出错误.我可以做mkdir blah 2>/dev/null但是我冒着失去其他错误消息的风险.
有没有人有任何想法为什么mkdir -p在scratchbox2下不起作用?
编辑
根据bobbogo的建议,我把它放在一起.它看起来相当复杂,但似乎工作,即使在scratchbox2下.
# Generic variables for use in functions
comma:= ,
empty:=
space:= $(empty) $(empty)
# Make directory function
forlooprange = $(wordlist 1,$(words $1),1 2 …Run Code Online (Sandbox Code Playgroud) 这是一个相当普通的STL容器封装,它允许Cfoo的用户迭代容器而不允许更改内部.
#include <vector>
class Cfoo
{
public:
class Cbar
{
/* contents of Cbar */
};
typedef std::vector<Cbar> TbarVector;
typedef TbarVector::const_iterator const_iterator;
public:
const_iterator begin() const { return( barVector_.begin() ); }
const_iterator end() const { return( barVector_.end() ); }
private:
TbarVector barVector_;
};
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.我们可以像这样迭代容器:
Cfoo myFoo;
for (Cfoo::const_iterator it = myFoo.begin(); it != myFoo.end(); ++it)
{
it->DoSomething();
}
Run Code Online (Sandbox Code Playgroud)
现在我想用一个嵌套的std :: vector替换std :: vector:
public:
typedef std::vector<Cbar> TbarVectorInner;
typedef std::vector<TbarVectorInner> TbarVectorOuter;
private:
TbarVectorOuter barContainer_;
Run Code Online (Sandbox Code Playgroud)
但我希望能够以与以前相同的方式迭代Cbar的所有实例,公开const_iterator,以及begin()const和end()const方法.
我不清楚如何做到这一点,虽然我怀疑它涉及编写自定义迭代器.有什么想法吗?
我正在开发一个使用生产者和消费者线程的linux应用程序.这是一个相当成熟的应用程序,我不想更改我的体系结构.
生产者和消费者线程通过可等待的队列链接.这是一个通过std :: queue与条件变量和互斥锁一起实现的类.
现在我希望消费者线程能够分叉/执行子进程,并等到子进程完成,或者等待队列非空,以先发生者为准.如果可等待队列非空,则必须终止子进程.编辑:子进程是无法更改的第三方应用程序.
一种可能性是当子进程终止时在我的条件变量上调用pthread_cond_signal(),但是如何实现呢?我不能使用SIGCHLD的处理程序,至少不能直接使用,因为手册页说pthread_cond_signal()不能从信号处理程序中使用.
一种可能的方法是生成子进程,然后启动一个线程到一个阻塞的waitpid(),最后是pthread_cond_signal().这看起来有点笨拙:我真的需要生成一个线程只是为了关注pid吗?
对于混合waitpid和select/poll/epoll,有Self Pipe Trick.混合waitpid和条件变量有没有相应的东西?
注1:在某些实现中,SIGCHLD中断条件变量等待函数.这是不可移植的,如果可能的话,我宁愿不依赖这种行为.
注意2:由于条件变量封装在可等待的队列类中,我需要扩展此类以允许应用程序发出互斥锁信号.这只是一个简单的实现细节,我在我的问题中掩盖了这一点.
我写了很多处理消息协议的代码。消息协议通常会具有通用的消息帧,可以从串行端口或套接字反序列化。该帧包含消息类型,并且必须根据消息类型来处理消息有效负载。
通常,我用访问器方法和构造函数编写一个多态类集,该构造函数引用消息框。
我想到的是,我可以直接从消息框架派生访问器类,然后从消息框架重新解释_cast到适当的访问器类,而不是基于对消息框架的引用来构造访问器类。这使代码更加简洁,并节省了一些字节和处理器周期。
请参见下面的示例(极度虚构和压缩)。显然,对于生产代码,所有这些都需要适当地封装,强制转换成为派生类的成员,更好地分离了所关注的问题,并添加了一些验证。为了简洁起见,已全部删除。
#include <iostream>
#include <cstring>
#include <vector>
struct GenericMessage
{
GenericMessage(const char* body):body_(body, body+strlen(body)){}
std::vector<char> body_;
};
struct MessageType1:public GenericMessage
{
int GetFoo()const
{
return body_[2];
}
int GetBar()const
{
return body_[3];
}
};
int main()
{
GenericMessage myGenericMessage("1234");
MessageType1* myMgessageType1 = reinterpret_cast<MessageType1*>(&myGenericMessage);
std::cout << "Foo:" << myMgessageType1->GetFoo() << std::endl;
std::cout << "Bar:" << myMgessageType1->GetBar() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我从来没有见过任何地方这样做。考虑到派生没有其他数据成员,以这种方式从基础到派生有任何不利之处吗?
我正在使用boost :: filesystem重命名文件,有时目标文件将存在。根据此处的升压文档:
http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/reference.html#Non-member-functions
模板无效重命名(const Path1&from_p,const Path2&to_p); 要求:Path1 :: external_string_type和Path2 :: external_string_type是同一类型。
效果:将from_p重命名为to_p,就像通过POSIX named()一样。
后置条件:!exists(from_p)&&存在(to_p),否则原先名为from_p的文件的内容和属性不变。
[注意:如果from_p和to_p解析为同一文件,则不执行任何操作。否则,如果to_p解析为现有文件,则将其删除。符号链接本身会重命名,而不是解析为重命名的文件。-尾注]
(我的重点)
在XP SP3上测试通过MS Visual Studio 2008编译的代码时,重命名会引发boost :: filesystem :: filesystem_error并显示以下消息:
该文件已存在时无法创建该文件
我注意到这是在错误报告中提出的:https : //svn.boost.org/trac/boost/ticket/2866
...但是声称在Boost 1.41.0中已关闭,而我正在使用Boost 1.42.0。
我在这里做错了还是应该恢复为std :: rename?
我还没有在Linux上测试过它,所以也不知道问题是否也存在。
在GNU Make中,我需要获取运行makefile的目录的父目录的名称.
例如,如果makefile是/ home/fnord/foo/bar/Makefile,我想将变量设置为字符串"foo".
我可以使用一些GNU Make内置函数来实现这一点,为了清楚起见,这里显示了所有这些功能.
V1=$(CURDIR)
V2=$(dir $(V1))
V3=$(subst /, ,$(V2))
V4=$(lastword $(V3))
Run Code Online (Sandbox Code Playgroud)
对于这样一个简单的要求,这似乎很复杂,但我找不到更好的方法.有没有更好的技术来分割GNU Make中的路径名?
我需要这个在GNU Make 3.81及更高版本中工作.
我有一个来自旧的颠覆服务器的tar备份,该服务器早已死亡.由此服务器管理的所有源代码都是遗留代码,除了这个项目之外,它将永远不再需要.
tar文件中充满了像"conf","dav","db"这样的小目录......
有没有办法从这个备份中提取单个项目的最终源代码?
可以创建内存中的 SQlite 数据库:
rc = sqlite3_open(":memory:", &db);
Run Code Online (Sandbox Code Playgroud)
但如果我理解了文档,那么该数据库对于创建它的应用程序来说是本地的。
我需要一个可以由多个应用程序访问的内存 SQLite 数据库。除了在虚拟磁盘上创建数据库之外,还有其他方法吗?
这是针对嵌入式Linux 平台的。
c++ ×5
c ×2
gnu-make ×2
boost ×1
const ×1
dry ×1
filesystems ×1
inheritance ×1
linux ×1
mkdir ×1
pthreads ×1
scratchbox ×1
sqlite ×1
stl ×1
svn ×1