要想顺利编译GRETA还真有点不容易呢,最近装了Win7,安装VS2008装不上就只有装VS2005,还有风险呢。
GRETA是一个微软员工Eric Niebler开发的开源正则引擎,可惜后面离开微软就没有再维护了。不过好东西还是值得学习使用的。
把相关的文件导进VS2005,编译出现如下错误:
1>e:/paper/regular expression/implements/greta/greta/restack.h(355) : warning C4346: “regex::hetero_stack<AlignmentT,RuntimeTypeCheckT,AssumePodT,DynamicBlockSizeT,StaticBlockSizeT>::stack_node::header”: 依赖名称不是类型
1> 用“typename”为前缀来表示类型
当然错误还有一些哪,先看第一个,因为经常很多错误都是有些关联的,解决一个说不定解决一堆看似无从下手的错误。看来VS很聪明啦,告诉你加一个前缀typename,的确是正确的。因为
byte_t m_buf[ aligned_sizeof<stack_node::header>::no_rtti + StaticBlockSizeT ];
编译器认为header不是一个类型,所以像下面这样写就正确了。但
byte_t m_buf[ aligned_sizeof<typename stack_node::header>::no_rtti + StaticBlockSizeT ];
那到底是不是呢?
struct stack_node
{
struct header
{
stack_node * m_back;
stack_node * m_next;
byte_t * m_current; // ptr into m_mem. alloc from here
byte_t * m_end; // ptr to last+1 byte_t in m_mem
};
union
{
header m_head;
byte_t m_align[ aligned_sizeof<header>::no_rtti ];
};
// This is the buffer into which values will be pushed and popped.
// It is guaranteed to meet the AlignmentT requirements because of
// the union above.
byte_t m_mem[1];
size_t size() const // throw()
{
return static_cast<size_t>( m_head.m_end - m_mem );
}
};
可以看到是一个类型,只是有点不明显,有点低调?所以加个typename来告诉编译器这是一个类型。C++对类内部定义的私有结构体内的内定义结构体的可见性,可访问性,我也不清楚。汗
既然是这样那应该还有一种解决办法,就是让它声明的明显一点。http://jimmy-c.javaeye.com/blog/182985上看到的一个办法:将上面那段程序改为:
struct stack_node_header;
struct stack_node
{
union
{
stack_node_header m_head;
byte_t m_align[ aligned_sizeof<stack_node_header>::no_rtti ];
};
// This is the buffer into which values will be pushed and popped.
// It is guaranteed to meet the AlignmentT requirements because of
// the union above.
byte_t m_mem[1];
size_t size() const // throw()
{
return static_cast<size_t>( m_head.m_end - m_mem );
}
};
struct stack_node_header
{
stack_node * m_back;
stack_node * m_next;
byte_t * m_current; // ptr into m_mem. alloc from here
byte_t * m_end; // ptr to last+1 byte_t in m_mem
};
然后将调用它的地方改为:
byte_t m_buf[aligned_sizeof<stack_node_header>::no_rtti + StaticBlockSizeT];
很明显stack_node_header是一个类型,我都看出来了,编译器应该比我厉害。这个方法对源码改动比较大,在大的项目中会有很大的风险,所以推荐前一种办法。
再次编译的确少了这个错误。但是还有一个棘手的:
1>e:/paper/regular expression/implements/greta/greta/restack.h(355) : error C2923: “regex::hetero_stack<AlignmentT,RuntimeTypeCheckT,AssumePodT,DynamicBlockSizeT,StaticBlockSizeT>::aligned_sizeof”:“regex::hetero_stack<AlignmentT,RuntimeTypeCheckT,AssumePodT,DynamicBlockSizeT,StaticBlockSizeT>::stack_node::header”不是参数“T”的有效 模板 类型变量
传给模板的参数是一个char* 类型的变量,可以肯定GRETA提供了对char* 和wchar_t*的偏特化支持(头文件可以看到)。为什么还会报不是有效的模板类型变量呢?我们的确传的是一个char*的变量,产生这样问题可能就是编译器不知道到底采用哪一个类型参数作为模板的实例化参数类型,这个只可能是VS配置的语言支持引起的。编译不知道怎么选的时候,只有我们可以帮他了。把项目的字符集改为未设置,或者把声明char*类型的字符串改为wchar_t*类型的。重新编译通过。
Over...