|
2011年7月11日
在我的上一篇随笔里的模板代码在vs2010下可以编译通过,在gcc 4.4.3下却报错,后来请教师兄说可能是gcc版本太低,对模板的要求更苛刻,他用的gcc 4.5编译可以通过,所以一时心血来潮编译安装个gcc 最新版,也就是gcc 4.6.1 我参照了这篇博客 http://www.iteye.com/topic/1111655 ,但是安装过程中遇到了些问题,这里记载下,希望给遇到相同问题的一个参考. 在gcc-4.6.1下configure时出来 check CLooG installed....no(差不多是这意思,具体错误信息忘了),我在Synaptic Package Manager里搜索cloog,将libcloog-ppl-dev和libcloog-pll0安装了,configure通过:-) make && make install 都顺利通过:-) 我编译我们的开源项目stupidalgorithm http://code.google.com/p/stupidalgorithm/ ,编译通过,但运行不通,提示需要库GLIBCXX_3.4.15,这时将 gcc-4.6.1/i686-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.16复制到/usr/lib,然后ln -s libstdc++.so.6 libstdc++.so.6.0.16,然后sudo ldconfig即可:-)
2011年7月9日
下面是示例代码,在vs2010下编译成功,但在linux下编译报错。 基类com_alg代码片段: 1 template <typename real_para> 2 class com_alg 3 { 4 public: 5 com_alg(std::string conf_path) 6 { 7 // 8 } 9 virtual ~com_alg() { } 10 }; 子类de_alg代码片段: 1 #include "com_alg.h" 2 3 class de_alg 4 :public com_alg<de_para> 5 { 6 public: 7 de_alg(std::string conf_path): 8 com_alg(conf_path) 9 { 10 } 11 ~de_alg() { } 12 }; 注意de_alg代码第8行红色部分,在vs2010下编译通过,但是在linux(g++ 4.4.3)下编译出错: de_alg.h: In constructor ‘de_alg::de_alg(std::string)’: de_alg.h:30: error: class ‘de_alg’ does not have any field named ‘com_alg’ de_alg.h:30: error: no matching function for call to ‘com_alg<de_para>::com_alg()’ com_alg.h:29: note: candidates are: com_alg<real_para>::com_alg(std::string) [with real_para = de_para] com_alg.h:27: note: com_alg<de_para>::com_alg(const com_alg<de_para>&) 将代码改为 com_alg<de_para>(conf_path)编译通过,大家能帮忙解释下不?
2011年3月22日
这段时间要写服务器负载均衡算法和调度策略,但我没有接触过这方面的知识,网上有很多方法,如 轮循法,加权轮循法,最小连接数调度等方法,我想用加权轮循,但对权植和如何分配服务器不太清楚,有谁了解的请教下,不胜感激....
2011年3月21日
前几天安装了win7,挺好用的,比xp用起来还是舒服多了,装完后ubuntu系统进不了了,几经折腾终于搞定,记载下...同时也告诫自己,系统遇到问题了要有耐心,慢慢总会找到解决方法的,怎么也比重装来的快,废话少说啦...
1. 用ubuntu live CD启动,打开终端.
2. 网上说的方法大致是:
sudo grub grub>find /boot/stage1 ---->输出(hdx,y) grub>root (hdx,y) grub>setup (hd0) grub>quit
但是我按照上面的方法 不是说file not found就是no device.然后运行了sudo grub-install --root-directory=/mnt /dev/sda 命令,再次执行上面步骤,成功.reboot
如果重启后系统出现grub,那么你是幸运的,我没那么幸运,系统进入grub命令模式, :-( grub>
这时候就要用到grub命令了,其实这时即可以进win7也可以进ubuntu,进ubuntu修复grub吧,命令如下
grub> find /boot/grub/core.img ----> (hdx,y) grub> root (hdx,y) grub> kernel /boot/grub/core.img grub> boot
这下就会启动linux,进入终端,输入sudo grub-install /dev/sda,OK
如果要进入win7,输入如下命令即可: grub> rootnoverify (hd0,0) grub> chainloader +1 grub> boot
:-)
2011年1月16日
pimp idiom的详细说明可以访 http://www.gotw.ca/gotw/024.htm(这个网站好像被墙了,很讽刺),其实就是将定义与实现分开。 在我博客上一篇随笔《关于高内聚低偶合》提到的问题,pimp idiom对降低程序偶合有一定的帮助,下面是我的理解思路,大家有好的意见或者更好的方法可以一起讨论下: 1 class Para_Base 2 { 3 // 4 }; 5 6 class GA_Para 7 :public Para_Base 8 { 9 // 10 }; 11 12 class Alg_Base 13 { 14 public: 15 Alg_Base(Para_Base *p) 16 :m_pPara(p) { } 17 // 18 protected: 19 Para_Base *m_pPara; 20 }; 21 22 class GA_Alg 23 :public Alg_Base 24 { 25 // 26 public: 27 GA_Alg(GA_Para *pGA) 28 :Alg_Base(pGA) { } 29 }; 参数基类Para_Base和特定的算法参数类GA_Para都没有改变。 算法基类Alg_Base的模板去掉了,同时添加了一个指向参数基类Para_Base的指针成员变量,而以前用的是模板指针。并且修改了构造函数,构造函数接受一个指向Para_Base的指针并赋给m_pPara。 特定算法类GA_Alg继承自算法基类Alg_Base,但修改了构造函数,接受指向GA_Para的一个指针,然后调用父类Alg_Base的构造函数,这样的结果便是m_pPara指向的是GA_Para实例,等价于Para_Base *m_pPara = new GA_Para(); 相对于上一篇提到的模板实现,pimp idiom的偶合更低些,而且pimp idiom应用也非常广泛。
2011年1月13日
最近遇到的一个问题,大伙来讨论一下,希望得到高手的指点,代码的结构是这样的: 1 class Para_Base 2 { 3 4 }; 5 6 class GA_Para 7 :public Para_Base 8 { 9 10 }; 11 12 template <typename Para_Type> 13 class Alg_Base 14 { 15 // 16 shared_ptr<Para_Type> m_pPara; 17 }; 18 19 class GA_Alg 20 :public Alg_Base<GA_Para> 21 { 22 23 } 解释一下,一个参数基类,是各种算法参数的公共基类,第二个类是GA算法的参数类,继承自Para_Base,第三个类是各种算法的基类,是个模板类,模板参数类型是算法参数类型,如GA_Para,第4个类是GA算法类,继承自Alg_Base ,这样m_pPara对不同的算法指向不同的参数,但这样改动一下代码,程序得从头重新编译,因为程序库的确比较大,编译起来挺花时间的,(这是师兄带我写的一个智能演化算法的库,即将完成,我们打算开源,完成后再通告大家)大家有没有更好的设计方法,比如把定义与实现分开,还望大家多发表些意见,不胜感激。
下面介绍如何从配置文件中读参数,配置文件中采用name = value的形式,#行表示注释. 1 #include <boost/program_options.hpp> 2 3 #include <vector> 4 #include <iostream> 5 #include <string> 6 #include <algorithm> 7 #include <iterator> 8 #include <fstream> 9 using std::copy; 10 using std::vector; 11 using std::string; 12 using std::cout; 13 using std::cerr; 14 using std::endl; 15 using std::exception; 16 using std::ostream; 17 using std::ifstream; 18 using std::ostream_iterator; 19 20 namespace po=boost::program_options; 21 22 // output vector. 23 template <typename T> 24 ostream& operator<<(ostream& os, const vector<T>& v) 25 { 26 copy(v.begin(), v.end(), ostream_iterator<T>(os, " ")); 27 return os; 28 } 29 30 int main(int argc, char*argv[]) 31 { 32 try 33 { 34 string conf_file; 35 po::options_description desc("general descriptions."); 36 desc.add_options() 37 ("help", "generate help information") 38 ("config,c", po::value<string>(&conf_file)->default_value("compiler.conf"), "compiler configure file") 39 ("input-file", po::value<vector<string> >(), "input files") 40 ("link-file,l", po::value<vector<string> >()->composing(), "link file"); 41 42 po::positional_options_description p; 43 p.add("input-file", -1); 44 45 po::variables_map vm; 46 //po::store(po::parse_command_line(argc, argv, desc), vm); 47 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); 48 po::notify(vm); 49 50 51 if(vm.count("help")) 52 { 53 cout<<desc<<endl; 54 return 1; 55 } 56 57 // add following lines 58 ifstream i_conf(conf_file.c_str()); 59 if(!i_conf) 60 { 61 cerr<<"Configure file not exit.\n"; 62 return -1; 63 } 64 else 65 { 66 po::store(po::parse_config_file(i_conf, desc), vm); 67 notify(vm); 68 } 69 70 if(vm.count("input-file")) 71 { 72 cout<<"Input files: "<<vm["input-file"].as<vector<string> >() 73 <<"\n"; 74 } 75 76 if(vm.count("link-file")) 77 { 78 cout<<"Link file: "<<vm["link-file"].as<vector<string> >() 79 <<"\n"; 80 } 81 } 82 catch(exception& e) 83 { 84 cout<<e.what()<<endl; 85 return -1; 86 } 87 88 return 0; 89 } 90 第38行添加了config参数命令,接受一个string类型值,并将默认值设为compiler.conf. 第40行添加了composing()方法,这表示程序将从不同的数据源中获得数据并组合起来. 第66行解析配置文件并存储至vm. 接下来代码便是比对vm中选项值,简单吧:) boost文档里介绍了隐藏选项和存放多姐选项的方法, http://www.boost.org/doc/libs/1_45_0/doc/html/program_options/tutorial.html#id2073299
boost program_options库可以帮助我们解析程序参数,支持命令行形式和配置文件形式,获得(name, value)对.下面我们以一个模拟编译器例子介绍program_options库的应用,在下一节继续介绍program_options整个库. 1 #include <boost/program_options.hpp> 2 3 #include <vector> 4 #include <iostream> 5 #include <string> 6 #include <algorithm> 7 #include <iterator> 8 using std::copy; 9 using std::vector; 10 using std::string; 11 using std::cout; 12 using std::endl; 13 using std::exception; 14 using std::ostream; 15 using std::ostream_iterator; 16 17 namespace po=boost::program_options; 18 19 // output vector. 20 template <typename T> 21 ostream& operator<<(ostream& os, const vector<T>& v) 22 { 23 copy(v.begin(), v.end(), ostream_iterator<T>(os, " ")); 24 return os; 25 } 26 27 int main(int argc, char*argv[]) 28 { 29 try 30 { 31 po::options_description desc("general descriptions."); 32 desc.add_options() 33 ("help", "generate help information") 34 ("input-file", po::value<vector<string> >(), "input files") 35 ("link-file,l", po::value<vector<string> >(), "link file"); 36 37 po::variables_map vm; 38 po::store(po::parse_command_line(argc, argv, desc), vm); 39 po::notify(vm); 40 41 if(vm.count("help")) 42 { 43 cout<<desc<<endl; 44 return 1; 45 } 46 47 if(vm.count("input-file")) 48 { 49 cout<<"Input files: "<<vm["input-file"].as<vector<string> >() 50 <<"\n"; 51 } 52 53 if(vm.count("link-file")) 54 { 55 cout<<"Link file: "<<vm["link-file"].as<vector<string> >() 56 <<"\n"; 57 } 58 } 59 catch(exception& e) 60 { 61 cout<<e.what()<<endl; 62 return -1; 63 } 64 65 return 0; 66 } 67 程序第20行重载了<<运算符,用于输出vector数组. 第31行定义一个选项描述组件,然后添加允许的选项,add_options()方法返回一个特定对象,该对象重载了()运算.link-file选项指定了短名l,这样--link-file与-l一个意思. 第37行定义一个存储器组件对象vm. 第38行分析器parse_command_line将选项描述存储至vm,这里用到的分析器很简单,后面会介绍更复杂的应用. 接下来的代码就是比对vm中存放的选项了,简单吧,很好理解.下面是运行截图,编译需要添加boost program_options库,即-lboost_program_option 对于input-file选项,每次都要输出--input-file真的很麻烦,能不能用compiler main.cpp呢,当然可以.这种选项叫做positional option, 在第36行处加上如下代码: 1 po::positional_options_description p; 2 p.add("input-file", -1); 3 修改第38行,我们要用到功能更强大的command_line_parse,改成如下: 1 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); 编译运行:看下结果吧 先到这里吧,接下来再看从文件中读选项:)
2011年1月11日
boost any库可以在如下三方面改善你的程序:(1)任意类型的类型安全存储以及安全的取回;(2)在标准库容器中存放不同类型的方法;(3)可以在无须知道类型的情况下传送类型。 1 boost::any a; //定义any对象 2 a=std::string("boost any"); //any重载了模板赋值函数 3 a=3.1415; 4 a=15; 5 6 std::string s("any type"); 7 boost::any b(s); //any的模板构造函数 8 从any对象中取出存放数据要借助普通模板函数any_cast,取回数据也很简单. 1 string ss=boost::any_cast<std::string>(b); 如果类型不符any_cast会抛出一个bad_any_cast异常,该异常继承自std::bad_cast.同时any对象有type()成员函数,可以比较类型后再进行类型转换. 1 2 if(a.type()==typeid(int)) 3 { 4 int i=boost::any_cast<int>(a); 5 //do something 6 } 7 else if(a.type()==typeid(std::string)) 8 { 9 std::string s=boost::any_cast<std::string>(a); 10 //do something 11 } 12 else 13 { 14 try 15 { 16 double d=boost::any_cast<double>(a); 17 //do something 18 } 19 catch(std::bad_cast& bc) 20 { 21 std::cout<<"Oops!"; 22 //do something 23 } 24 } 25 说明:any类成员函数empty()用于判断对象中是否为空,在用any存放指针时要特别注意,any不保证指针非空,即存放空指针时empty()返回还是false.看如下代码片段便知: 1 int *p=0; 2 a=p; 3 if(!a.empty()) 4 { 5 cout<<"a is not empty.\n"; 6 } 7 else 8 { 9 cout<<"a is empty.\n"; 10 } 11 输出结果为 a is not empty.所以我们要额外判断指针是否为空. 1 if(!a.empty()) 2 { 3 if(boost::any_cast<int*>(a) != 0) 4 cout<<"a is not empty.\n"; 5 else 6 cout<<"null pointer.\n"; 7 } 8 else 9 { 10 cout<<"a is empty.\n"; 11 } 12 any存放类指针支持多态.
2011年1月10日
boost progress包括progress_timer, progress_display,分别用于输出程序运行的时间和显示运行进度. 1
2 #include <boost/progress.hpp>
3
4 #include <iostream>
5 #include <vector>
6
7 using std::cout;
8 using std::endl;
9 using std::vector;
10 using boost::progress_display;
11 using boost::progress_timer;
12
13 int main()
14 {
15 vector<int> v;
16 int i;
17 for(i=0; i<10; i++)
18 v.push_back(i);
19
20 progress_display display(v.size());
21
22 vector<int>::iterator it;
23 progress_timer elapsed;
24 for(it=v.begin(); it!=v.end(); ++it)
25 {
26 //do something
27 ++display;
28 }
29
30 cout<<"elapsed time: ";
31 return 0;
32 } 程序运行结果截图: 说明:progress_display重载了operator++,progress_timer在定义时开始计时,对象析构时输出所耗时间.
|