_skyfly

我不要在IT中迷失方向

2007年1月25日 #

[C++/property模板类]使用时两个报错的解决办法

今天在项目中使用了C++的proper模板类,这个模板类是用来完成其它支持属性的语言关键字“属性”类似作用的。

在我的代码库内收藏了Achilleas Margaritis编写的C++ object properties library。很吸引人而且实用的功能。可惜在我的VS2005中使用时发生了以下两个错误,错误经定位后均出现在property.hpp中:
1、   出错代码:
typedef _property1<C, T>::_property2<A, S> base_class;
         错误提示:
warning C4346: “cpp::properties::_property1<C,T>::_property2<A,S>”: 依赖名称不是类型,用“typename”为前缀来表示类型;

2、   出错代码:
class interface {};
         错误提示:
error C2332: “class”: 缺少标记名;

*********************************************************
问题1很快查到原因:
*********************************************************
作者:Scott Meyers
译者:fatalerror99 (iTePub's Nirvana)

nested dependent name(嵌套依赖名字)会导致解析困难。例如,假设我们更加愚蠢地
以这种方法开始 print2nd:

template<typename C>
void print2nd(const C& container)
{
  C::const_iterator * x;
  ...
}

这看上去好像是我们将 x 声明为一个指向 C::const_iterator 的 local variable(局
部变量)。但是它看上去如此仅仅是因为我们知道 C::const_iterator 是一个 type(
类型)。但是如果 C::const_iterator 不是一个 type(类型)呢?如果 C 有一个 st
atic data member(静态数据成员)碰巧就叫做 const_iterator 呢?再如果 x 碰巧是
一个 global variable(全局变量)的名字呢?在这种情况下,上面的代码就不是声明
一个 local variable(局部变量),而是成为 C::const_iterator 乘以 x
!当然,这
听起来有些愚蠢,但它是可能的,而编写 C++ 解析器的人必须考虑所有可能的输入,甚
至是愚蠢的。

直到 C 成为已知之前,没有任何办法知道 C::const_iterator 到底是不是一个 type(
类型),而当 template(模板)print2nd 被解析的时候,C 还不是已知的。C++ 有一
条规则解决这个歧义:如果解析器在一个 template(模板)中遇到一个 nested depen
dent name(嵌套依赖名字),它假定那个名字不是一个 type(类型),除非你用其它
方式告诉它。缺省情况下,nested dependent name(嵌套依赖名字)不是 types(类型
)。(对于这条规则有一个例外,我待会儿告诉你。)

知道原因就简单了,直接把代码修正为:
typedef typename _property1<C, T>::_property2<A, S> base_class;
问题解决(只能说在Windows平台下VS自带的C++编译器问题解决,其它编译器甚至其它平台上的编译器我可没有去试过)。

*********************************************************
问题2我没查到原因,因为我直接按控制台项目创建示例代码时没出现这样的错误,而在Win32项目创建项目示例代码时就出现这样的报错。因为我大胆猜测,应当VS2005其自带的C++编译器为了支持C++/CLI,将interface列为关键字的缘故。因此编译器认为class interface是两个关键字的罗列,所以才会报“缺少标记名”。所以我的做法如下:
*********************************************************

把property.hpp(就是那个实现property模板类的文件)中所有涉及“interface”的地方完全替换为“_interface”,同时为保持风格统一,将property模板类中所有作用相同的类全修改为下划线开头!(_variable/_read_write/_read_only/_write_only),问题搞定!

不知道Achilleas Margaritis看到了我的解决方案是不是哭笑不得,哈哈~~

posted @ 2007-01-25 15:54 龙井2008 阅读(2085) | 评论 (3)编辑 收藏

2006年11月16日 #

WTL 8.0的程序生成向导调整后方可使用

从我开始安装了VS2005以后,我的WTL8.0的程序生成向导就一直不能使用。最近几次开发程序我一直都是在以前开发代码的基础上进行变动。这段时间计划要开发一个比较大的系统,我终于无法忍受这种拷贝粘贴再改动的状况,彻底研读分析程序生成向导的脚本。

还好,终于给我找到了问题的症结。原来错误不止一处:

1、WTL80\AppWiz\Files\HTML\1033的目录下的三个文件都存在同一处问题,导致向导无法执行:
       AppType.htm的第443到451行、default.htm的第509到517行、UIFeatures.htm的第516到524行:

         < SCRIPT >
    
var  strPath  =  window.external.FindSymbol( " PRODUCT_INSTALLATION_DIR " );
    strPath 
+=   " VCWizards/ " ;
    strPath 
+=  window.external.GetHostLocale();
    
var  strScriptPath  =  strPath  +   " /Script.js " ;
    
var  strCommonPath  =  strPath  +   " /Common.js " ;
    document.scripts(
" INCLUDE_SCRIPT " ).src  =  strScriptPath;
    document.scripts(
" INCLUDE_COMMON " ).src  =  strCommonPath;
        
</ SCRIPT >

      需要修改为:
        <SCRIPT>
    document.scripts(
"INCLUDE_SCRIPT").src = window.external.FindSymbol("SCRIPT_COMMON_PATH"+ "/Script.js";
    document.scripts(
"INCLUDE_COMMON").src = window.external.FindSymbol("SCRIPT_COMMON_PATH"+ "/Common.js";
        
</SCRIPT>
    
      原因是Script.js与Common.js两个文件的路径指向错误,因此无法读取这两个文件中的所定义的函数。

2、WTL80\AppWiz\Files\HTML\1033\default.htm的第21到22行的标签未封闭,直接删掉:
        <!-- This closing tag is here only to avoid security warning -->
        
</OBJECT>

3、WTL80\AppWiz\Files\HTML\1033的目录下的三个文件AppType.htm、default.htm、UIFeatures.htm的排版格式有问题,导致向导页面无法正常显示,直接在VS2005中打开进行编辑,将多余的空行删掉,把窄的表格拉宽。搞定。

现在就可以正常的使用WTL的程序生成向导了,我比较奇怪的是,难道没有其它的同仁们发现这个问题的么,反正我在google和baidu上都没有查到解决方案。

我已经将这三个文件打包了,需要用的同仁可以下载覆盖一下:
WTL8.0程序生成向导修复文件

posted @ 2006-11-16 15:03 龙井2008 阅读(2194) | 评论 (7)编辑 收藏

2006年8月10日 #

boost在路上...tokenizer [转贴]

tokenizer - Break of a string or other character sequence into a series of tokens, from John Bandela
tokenizer - 分解字串,提取内容.作者: John Bandela

例一:
// simple_example_1.cpp
#include<iostream>
#include<boost/tokenizer.hpp>
#include<string>

int main(){
   using namespace std;
   using namespace boost;
   string s = "This is,  a test";
   tokenizer<> tok(s);
   for(tokenizer<>::iterator beg=tok.begin(); beg!=tok.end();++beg){
       cout << *beg << "\n";
   }
}

输出
This
is
a
test

tokenizer默认将单词以空格和标点为边界分开.

例二:
#include<iostream>
#include<boost/tokenizer.hpp>
#include<string>

int main(){
   using namespace std;
   using namespace boost;
   string s = "Field 1,\"putting quotes around fields, allows commas\",Field 3";
   tokenizer<escaped_list_separator<char> > tok(s);
   for(tokenizer<escaped_list_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg){
       cout << *beg << "\n";
   }
}
输出
Field 1
putting quotes around fields, allows commas
Field 3

双引号之间可以有标点.


例三:
// simple_example_3.cpp
#include<iostream>
#include<boost/tokenizer.hpp>
#include<string>

int main(){
   using namespace std;
   using namespace boost;
   string s = "12252001";
   int offsets[] = {2,2,4};
   offset_separator f(offsets, offsets+3);
   tokenizer<offset_separator> tok(s,f);
   for(tokenizer<offset_separator>::iterator beg=tok.begin(); beg!=tok.end();++beg){
       cout << *beg << "\n";
   }
}

把12252001分解为
12
25
2001

例4:
// char_sep_example_1.cpp
#include <iostream>
#include <boost/tokenizer.hpp>
#include <string>

int main()
{
  std::string str = ";!!;Hello|world||-foo--bar;yow;baz|";
  typedef boost::tokenizer<boost::char_separator<char> >
    tokenizer;
  boost::char_separator<char> sep("-;|");
  tokenizer tokens(str, sep);
  for (tokenizer::iterator tok_iter = tokens.begin();
       tok_iter != tokens.end(); ++tok_iter)
    std::cout << "<" << *tok_iter << "> ";
  std::cout << "\n";
  return EXIT_SUCCESS;
}

输出
<!!> <Hello> <world> <foo> <bar> <yow> <baz>
自定义分隔的标点

例5:
    // char_sep_example_2.cpp
    #include <iostream>
    #include <boost/tokenizer.hpp>
    #include <string>

    int main()
    {
        std::string str = ";;Hello|world||-foo--bar;yow;baz|";
        typedef boost::tokenizer<boost::char_separator<char> >
            tokenizer;
        boost::char_separator<char> sep("-;", "|", boost::keep_empty_tokens);
        tokenizer tokens(str, sep);
        for (tokenizer::iterator tok_iter = tokens.begin();
             tok_iter != tokens.end(); ++tok_iter)
          std::cout << "<" << *tok_iter << "> ";
        std::cout << "\n";
        return EXIT_SUCCESS;
    }

The output is:

    <> <> <Hello> <|> <world> <|> <> <|> <> <foo> <> <bar> <yow> <baz> <|> <>
去除-; , 保留|但将它看作是分隔符,当两个分隔符相邻的时候会自动加空格

例6:
    // char_sep_example_3.cpp
    #include <iostream>
    #include <boost/tokenizer.hpp>
    #include <string>

    int main()
    {
       std::string str = "This is,  a test";
       typedef boost::tokenizer<boost::char_separator<char> > Tok;
       boost::char_separator<char> sep; // default constructed
       Tok tok(str, sep);
       for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter)
         std::cout << "<" << *tok_iter << "> ";
       std::cout << "\n";
       return EXIT_SUCCESS;
    }

The output is:

    <This> <is> <,> <a> <test>
保留标点但将它看作分隔符

posted @ 2006-08-10 09:39 龙井2008 阅读(556) | 评论 (0)编辑 收藏

Boost:UTF-8 Codecvt Facet(unicode 和 utf-8 之间相互转码) [转贴]

(原载:http://www.cppblog.com/zuroc/)

看到有前辈写了一个UTF-8与UNICODE相互转换的代码,顺便提一下,希望可以给大家提供一点帮助.
下面是一些编码格式的bit长

Examples of fixed-width encoding forms:

Type Each character
encoded as
Notes
  7-bit a single 7-bit quantity example: ISO 646
  8-bit G0/G1 a single 8-bit quantity with constraints on use of C0 and C1 spaces
  8-bit a single 8-bit quantity with no constraints on use of C1 space
  8-bit EBCDIC a single 8-bit quantity with the EBCDIC conventions rather than ASCII conventions
16-bit (UCS-2) a single 16-bit quantity within a code space of 0..FFFF
32-bit (UCS-4) a single 32-bit quantity within a code space 0..7FFFFFFF
32-bit (UTF-32) a single 32-bit quantity within a code space of 0..10FFFF
16-bit DBCS process code a single 16-bit quantity example: UNIX widechar implementations of Asian CCS's
32-bit DBCS process code a single 32-bit quantity example: UNIX widechar implementations of Asian CCS's
DBCS Host two 8-bit quantities following IBM host conventions

Examples of variable-width encoding forms:

Name Characters are encoded as Notes
UTF-8 a mix of one to four 8-bit code units in Unicode
and one to six code units in 10646
used only with Unicode/10646
UTF-16 a mix of one to two 16 bit code units used only with Unicode/10646

Boost中提供了一个UTF-8 Codecvt Facet,可以在utf8和UCS-4(Unicode-32)之间转换.
使用方式如下

  //...
  // My encoding type
  typedef wchar_t ucs4_t;

  std::locale old_locale;
  std::locale utf8_locale(old_locale,new utf8_codecvt_facet<ucs4_t>);

  // Set a New global locale
  std::locale::global(utf8_locale);

  //  UCS-4 转换为 UTF-8
  {
    std::wofstream ofs("data.ucd");
    ofs.imbue(utf8_locale);
    std::copy(ucs4_data.begin(),ucs4_data.end(),
          std::ostream_iterator<ucs4_t,ucs4_t>(ofs));
  }

  // 读入 UTF-8 ,转换为 UCS-4 
  std::vector<ucs4_t> from_file;
  {
    std::wifstream ifs("data.ucd");
    ifs.imbue(utf8_locale);
    ucs4_t item = 0;
    while (ifs >> item) from_file.push_back(item);
  }
  //...
UTF-8 Codecvt Facet详见
http://www.boost.org/libs/serialization/doc/codecvt.html

posted @ 2006-08-10 09:38 龙井2008 阅读(3856) | 评论 (0)编辑 收藏

2006年8月1日 #

VC8问题:升级后重编译程序,atlplus.h无法识别CStringW,请问各位是否遇到同类问题(此贴原载CSDN)


系统在VC7.1下开发,一直没问题,最近升级到VC8,然后重新编译,报如下错误:

d:\program files\microsoft visual studio 8\vc\atlmfc\include\atlplus.h(647) : error C2065: 'CStringW' : undeclared identifier
d:\program files\microsoft visual studio 8\vc\atlmfc\include\atlplus.h(647) : error C2146: syntax error : missing ';' before identifier 'strW'
d:\program files\microsoft visual studio 8\vc\atlmfc\include\atlplus.h(647) : error C3861: 'strW': identifier not found

但是在atlplus.h中明明已经include过atlstr.h:
...
#include <shellapi.h>
#include "atlevent.h"
#include <cstringt.h>
#include <atlstr.h>
//Avoid using <atlstr.h> except in the registry templates (for circular dependencies).

[
provider(name="ATL4", uuid="BC6B4B8A-0E4A-4bc9-B319-9DC2ACFB61EE")
];
...
...
GetStringAtLoc(rgStrings, dwValue, rgBytes, &szReplacement);
CStringW strW(szReplacement ? szReplacement : rgBytes.m_aT); // 在该行报错
...

已经查了很久,没有解决办法,请问有朋友遇到过类似的情况没有,最后如何解决的?

======================

问题暂时解决,办法如下:

1、在atlplus.h中,用<stdstring.h>代替<atlstr.h>:
(stdstring.h是Joe O'Leary编写的用于取代完整取代CString的类,基于std::string)

#include <stdstring.h>

2、修改报错行:
CStringW strW(szReplacement ? szReplacement : rgBytes.m_aT); // 在该行报错

修改为:
CStdStringW strW(szReplacement ? szReplacement : rgBytes.m_aT); // 该行通过

现在编译已通过,但由于我改变了系统文件<atlplus.h>的内容,给atl额外引入了stl的负担,会影响atl完整性和高效性。该解决办法是很不恰当的。

还请各位高人给出合适的解决办法,谢谢。

posted @ 2006-08-01 21:12 龙井2008 阅读(1148) | 评论 (0)编辑 收藏

2006年6月22日 #

程序运行后,立即隐藏到系统栏内 ( 期待更好的解决办法 )。

我写了一个程序,每N秒,定时对数据库进行刷新,以修正数据库内的一些数据。我把它放在启动菜单栏里,希望一开机就运行。同时希望程序一运行就隐藏到系统栏,这样不影响我使用其它程序。

本来我是想直接在CMainDlg::OnInitDialog中用ShowWindow(SW_HIDE);的,但是很不幸,程序窗口依然显示。在网上查找一段时间以后没有找到解决办法,只好自行摸索了。

最后我是通过延时发隐藏窗口请求来解决的(先显示窗口,等待一段时间,再隐藏窗口)。我想主窗口在CMainDlg::OnInitDialog中不能隐藏的原因,是该函数运行后,还有一些事件刷新了主窗口,所以我通过延时等待所有的主窗口事件处理完成以后再进行隐藏。

在CMainDlg::OnInitDialog中:

//  设置定时间隔
SetTimer(IDT_TIMER_TOSYSTRAY,DELAY_TIME * 1000 );

在CMainDlg::OnTimer中:
switch(wParam)
{
case IDT_TIMER_TOSYSTRAY:
    
// 隐藏窗口到系统栏
    KillTimer(IDT_TIMER_TOSYSTRAY);
    SendMessage(WM_CLOSE);
    
break;
case IDT_TIMER_REFRESH:
    
break;
}

真正的处理函数:
LRESULT CMainDlg::OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    
// TODO: Add your message handler code here and/or call default
    if (IsWindowVisible())
        ShowWindow(SW_HIDE);
    
return 0;
}

posted @ 2006-06-22 16:54 龙井2008 阅读(619) | 评论 (2)编辑 收藏

2006年6月16日 #

无法从IIS服务器上下载.tab类型文件

我在公司的文件服务器上起了IIS 6 Web服务,在某目录内放置了.TAB文件(超级报表格式),但是用浏览器下载文件的时候报错,无法下载。

进入文件服务器上的IIS 管理器,右击“网站”==>“网站属性”,选择“http头”,再选择“MIME类型” ==> “新建”
==>“扩展名”:.tab(注意,tab前面有点)==>“MIME类型”:application/ChinaExcel

问题解决,在客户端可以下载文件,如果客户端安装了ChanaExcel程序,则可以通过IE直接打开文件。

原因:
见IIS6 属性页上的“MIME”描述:IIS只为扩展名在MIME类型列表中注册了的文件提供服务。.TAB为非标准文件后缀名,因此需要在IIS中进行注册,IIS对未注册文件不予处理。

posted @ 2006-06-16 09:44 龙井2008 阅读(550) | 评论 (0)编辑 收藏

2005年10月10日 #

SVG使用体会

这些天来研究XML的各类应用。前天花了近一天的时间来研究SVG图形文件格式。发现这个规范的确很好,如果研究好了,以后就应用在项目上,应该很酷的。

不过试验的时候,老是中文无法显示,搞得我灰头灰脸的。都怀疑我是不是弱智了。

按以前处理xml文件的经验,我先把语言编码加入SVG。呵呵,这里犯了一个错误,因此我的xmlWriter认为不是良好格式文档。原来是顺序声明错误啦。
<?xml version="1.0" standalone="no" encodeing="GB2312" ?>,能看出来哪儿错了吗,原来应当写成
<?xml version="1.0" encodeing="GB2312" standalone="no" ?>,晕,没细看标准的代价,害得我在网上查来查去。

但是这样还是不能显示中文,再晕~~~~~~~~~~,再去网上查~~~~~~~~,哈哈,原来有人也遇到过这个问题哟,网上牛人蛮多呀,前辈哟,看看eureka的心得(http://www.ee-studio.com/drupal/node/447/print):

好多SVG编辑器都有不能正常支持中文,后来自己手工创建SVG文件,却也不能在浏览器插件里正常显示。还以为是插件问题(如adobe svg viewer和corel svg viewer等),象我用inkscape,就能很好的处理中文,但却不能在浏览器里正常显示!不知为什么,还真以为插件问题。查看svg viewer的技术规范,都说是支持utf-8的,那是什么问题呢?难道是文字编码问题,后来几经测试,用各种编码及encoding头,还是不对劲。

后来我好不容易总算琢磨出问题所在,原来你必须给中文加上中文字体。看来adbobe svg viewer和corel svg viewer缺省都没有带支持某种中文字体的,不象inkscape,能正常显示中文。因此,在这种情况下,给中文加上某种字体的样式,就可以正常显示而不是一些框框了,包括从W3C来的一些SVG中文幻灯片,给它加上中文某中字体的样式才行!

不过我用的编辑器里,webdraw 和 xstudio还是不支持中文的!不能很好的处理,只有inkscape,能很好的支持中文。但它不带有原生的SVG代码编辑,其xml editor是对节点进行编辑的,不能对原文件进行编辑。呵呵,事物总是不断发展吧。

哈哈,这不正是我要的吗,试试去喽。感谢eureka!

posted @ 2005-10-10 09:54 龙井2008 阅读(1370) | 评论 (2)编辑 收藏

2005年9月22日 #

常用到的网络资源

一、软件开发资源:
http://www.dreambrook.com/

二、BLOG
http://blog.csdn.net/lwklchj/  力挽狂澜的家

三、考试资源
http://www.kejiedu.cn/ruankao/index/index.php 南京科技教育局

posted @ 2005-09-22 09:27 龙井2008 阅读(324) | 评论 (1)编辑 收藏

2005年9月14日 #

软件的编码转换

  从上周开始,我开始将以前自己所做的Res3项目转化成UNICODE格式。

  这个做法的动力来源有两个:
  一个就是人云亦云啦,看到不少文章中都说了UNICODE编码的好处,也有些心动。

  第二个原因是,我对目前开发的整个项目的远景构想,是想把这个项目拆解成很多小的部分。使得这些小的项目资源可以提供给以后其它的项目使用。每个部分不管是对内还是对外的接口,都尽量依据现有的标准来开发完成。例如UNICODE、WebService、XML等等。

  这次是我所做的一个小试验,来验证自己的想法是否可行,真是不做不知道,原先我认为将现有的代码转换成支持UNICODE,应当是一件很容易的事情。做起来才晓得,由于自己以前完全没有考虑过这种转换,很多遗留的代码,比如文字常量,都要手工进行转换。也许以后,我应当写出一个小的转换程序,用来辅助完成任务。

  还有一个困难,就是我以前经常使用的开源代码,很多代码也是没有考虑到到UNICODE编码,这种情况下,我要么对源代码进行了修改,要么就换用了其它支持UNICODE的开源代码。好可惜哟,有些代码在ANSI下很好用的,现在只好放弃。

  这次UNICODE转换试验完成后,会有很多心得,我会再整理记录下来,免得以后再走弯路。

posted @ 2005-09-14 14:30 龙井2008 阅读(394) | 评论 (0)编辑 收藏

仅列出标题  下一页