gnu编译C++11,最好与win32公用代码

看makefile:

#jingz's first file to test makeFile
allTarget:stdafx_target 11_12_target
	g++ stdafx.o functor-adapter_p431.o -o functor-adapter_p431.exe
#remove the object files
	rm -rf stdafx.o functor-adapter_p431.o
#complie the cpps into objects
stdafx_target:
	g++ -std=c++11 -c stdafx.cpp -o stdafx.o
11_12_target:
	g++ -std=c++11 -c functor-adapter_p431.cpp -o functor-adapter_p431.o

平时使用vs、xcode等ide,老是忽略预编译命令,还是得吃

-std=c++11 C++11的预编译定义,因为gnu默认关闭C++11特性

比较多家的编译器是有所区别的,根据实际情况使用预编译处理。

1)比如tchar相关:

#ifdef WIN32
#include "targetver.h"
#include <tchar.h>
#endif

如果是cocos2dx,则可以使用CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 这类似预编译定义处理跨平台的兼容问题

// functor-adapter_p431.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <algorithm>//元素操作算法
#include <functional> //函数配接器,bind、compose、negate
#include <iostream>
#include <iterator>
#include <vector>
#include <memory>

using std::cout;
using std::cin;
using std::endl;

bool print(int i)
{
	std::cout<< i << " ";
	return true;
}

class Int
{
public:
	explicit Int(int i):m_i(i){};
	~Int(void){};

	void print1(void) const
	{
		cout<<"["<<m_i<<"]";
	}
	void print2(Int &i)const
	{
		cout<<"["<<i.m_i<<"]";
	}
	static void print3(Int &i)
	{
		cout<<"["<<i.m_i<<"]";
	}

	void addNum(int j)
	{
		m_i+=j;
	}

int m_i;

private:

};

Int operator + (const Int &lhi,const Int &rhi)
	{
		Int temp(lhi.m_i);
		temp.m_i+=rhi.m_i;
		return temp;
	}

typedef bool (*FunPtr)(int);
typedef std::function<void ()> FunObejct;  

class A
{
public:
    virtual void f()
    {
        std::cout<<"A::f()"<<endl;
    }  

    void init()
    {
        //std::bind可以表现出多态行为
        FunObejct f=std::bind(&A::f,this);
        f();
    }
	bool print(int i)
	{
		std::cout<< i << ":";
		return true;
	}

	inline bool operator() (int i)
	{
		std::cout<< i << "/";
		return true;
	}

};  

class B:public A
{
public:
    virtual void f()
    {
        cout<<"B::f()"<<endl;
    }
};  

void inc(int &a)
{
	++a;
}

#ifdef WIN32
int _tmain(int argc, _TCHAR* argv[])
#else
int main(int argc, char* argv[])
#endif
{
	std::ostream_iterator<int> out_it(cout,",");//输出迭代器绑定到命令窗输出行中,每次输出填充一个,和print区别开来

	int ia[6] = {2,21,12,7,19,23};

	std::shared_ptr<A>pa(new B()); //父类指针指向子类对象
    pa->init(); //多态、函数绑定实现的多台
	/*
	*
	template<class _Ret,
	class _Rx,
	class _Farg0,
	class _Arg0> inline
	typename enable_if<!is_same<_Ret, _Rx>::value,
		_Bind<true, _Ret, _Pmd_wrap<_Rx _Farg0::*, _Rx, _Farg0>, _Arg0>
			>::type
		bind(_Rx _Farg0::* const _Pmd, _Arg0&& _A0)
	{	// bind a wrapped member object pointer
	return (_Bind<true, _Ret,
		_Pmd_wrap<_Rx _Farg0::*, _Rx, _Farg0>, _Arg0>(
		_Pmd_wrap<_Rx _Farg0::*, _Rx, _Farg0>(_Pmd),
			_STD forward<_Arg0>(_A0)));
	}
	*
	*
	*/
	std::function<bool(int)> printInt = std::bind(&B::print,pa,std::placeholders::_1);//
	std::function<bool(int)> printInt2 = std::bind(&A::print,pa,std::placeholders::_1);
	printInt(1000);
	printInt2(1002);

	typedef std::function<bool(int)> FP;

	FP t_fp = FP(print);

	t_fp(12);
	cout<<endl;

	//找出不小于12的数据
	std::vector<int> iv(ia,ia+6);
	std::copy_if(iv.begin(),iv.end(),out_it,std::not1(std::bind2nd(std::less<int>(),12)));

	//cout<< std::count_if(ia,ia+6,std::not1(std::bind(f1,12)) )<<endl;

	cout<<endl;

	int nums = std::count_if(
		iv.begin(),iv.end(),
		std::bind(
			std::logical_and<bool>(),
			std::bind(std::less<int>(),std::placeholders::_1,30),
			std::bind(std::greater<int>(),std::placeholders::_1,12)
			)
		);
	cout<<"(12,30):"<<nums<<endl;
	//在循环内部讲执行这样一句代码:_Pred(*first)。_Pred就是函数对象std::bind(std::less<int>(),std::placeholders::_1,12)产生的对象
	int nums2= std::count_if(iv.begin(),iv.end(),std::bind(std::less<int>(),std::placeholders::_1,12));
	cout<<"(-,12):"<<nums2<<endl;

	//使用迭代器输出所以数据
	std::copy(iv.begin(),iv.end(),out_it);
	cout<<endl;

	//使用函数名输出
	std::for_each(iv.begin(),iv.end(),print);//类中的函数操作保存在某个位置,我要阅读其他书籍才知道。仿函数对象指的一个仿函数对象,普通函数对象就是函数名,待续
	cout<<endl;

	//使用仿函数对象输出,需要通过指针处理,因为stl函数库的定义使用的模板,不进行类型检查(同时ide也无法完成成员提醒,因为未特化不存在改类型类型相关的代码),
	//只要存在operator()重载即可通过编译。如果使用pa传值,内部调用的()操作符,但是原生指针类型没有进行operator()操作的,会编译报错。
	std::for_each(iv.begin(),iv.end(),(*pa));
	cout<<endl;

	FunPtr fp1 = print; //函数指针和函数名是同一个东西?
	fp1(10);
	cout<<endl;

	//使用函数指针输出
	std::for_each(iv.begin(),iv.end(),fp1);//类中的函数操作保存在某个位置,我要阅读其他书籍才知道。仿函数对象指的一个仿函数对象,普通函数对象就是函数名,待续
	cout<<endl;

	//修饰过一般函数的STL算法,这个东西还没看,一点都不懂
	std::for_each(iv.begin(),iv.end(),std::ptr_fun(fp1));//使用包装好的函数最后调用结构std::ptr_fun(*begin()),里面执行的则是fp1(*begin())
	cout<<endl;

	std::vector<int> iv3;
	std::copy(iv.begin(),iv.end(),std::back_inserter(iv3));//back_inserter 是返回迭代器的函数,就像一个适配器。名为迭代器适配器,和本例子的函数适配器相仿,用于不同的场景

	std::for_each(iv3.begin(),iv3.end(),print);//如果使用非指向函数名的指针,会报错
	cout<<endl;

//	#define _BIND_IMPLICIT1( //	TEMPLATE_LIST1, PADDING_LIST1, LIST1, COMMA1, //	TEMPLATE_LIST2, PADDING_LIST2, LIST2, COMMA2) //template<class _Rx //	COMMA1 LIST1(_CLASS_TYPE) //	COMMA2 LIST2(_CLASS_TYPEX)> inline //	_Bind<true, _Rx, _Rx (* const)(LIST1(_TYPE)) COMMA2 LIST2(_TYPEX)> //		bind(_Rx (*_Pfx)(LIST1(_TYPE)) COMMA2 LIST2(_TYPEX_REFREF_ARG)) //	{	/* bind a function pointer */ //	return (_Bind<true, _Rx, _Rx (* const)(LIST1(_TYPE)) //		COMMA2 LIST2(_TYPEX)>(_Pfx COMMA2 LIST2(_FORWARD_ARGX))); //	}
	//注:COMMA:逗号,传参使用的是_TYPEX_REFREF_ARG
	/*
	1: #define _TYPEX_REFREF(NUM)			_VAR_TYPEX(NUM)&&

	2:#define _FORWARD_ARGX(NUM)		_STD forward<_VAR_TYPEX(NUM)>(_VAR_VALX(NUM))

	_VAR_TYPEX 是右值类型,所以再调用跳转的过程中,估计发生了的事情:n被转化为右值类型然后产生了某个副本,

	正解:std::forward<T>(u) 有两个参数:T 与 u。当T为左值引用类型时,u将被转换为T类型的左值,否则u将被转换为T类型右值。
	如此定义std::forward是为了在使用右值引用参数的函数模板中解决参数的完美转发问题。

	*/

	int n = 0;
	std::bind(inc,n)();//源码中使用的是
	print(n);//还是0;

	std::bind(inc,std::ref(n))();
	print(n);//终于是1啦。

	Int t1(3),t2(7),t3(20),t4(14),t5(26);

	std::vector<Int> vInt2;
	vInt2.push_back(t1); //cocos2dx中的testcpp有段反射代码,可以考虑用上来,短期险熟悉C++11的stl
	vInt2.push_back(t2);
	vInt2.push_back(t3);
	vInt2.push_back(t4);
	vInt2.push_back(t5);

//mem_fun则是质变算法。当for_each
//两者区别:
//mem_fun_ref的作用和用法跟mem_fun一样,唯一的不同就是:
//当容器中存放的是对象实体的时候用mem_fun_ref,
//当容器中存放的是对象的指针的时候用mem_fun。

	//error C3867: “Int::print1”: 函数调用缺少参数列表;请使用“&Int::print1”创建指向成员的指针
	std::for_each(vInt2.begin(),vInt2.end(),std::mem_fun_ref(&Int::print1));//如果使用非指向函数名的指针,会报错
	cout<<endl;
	;

	std::for_each(vInt2.begin(),vInt2.end(),std::bind(Int::print3,std::placeholders::_1));//只要保证函数接口的正确性就可以,std::bind构造函数的首参数一定是提供operator()的对象,可以是仿函数和函数名,使用静态是因为由函数操作对象,而不是访问对象的操作

	//std::for_each(vInt2.begin(),vInt2.end(),std::mem_fun_ref(&std::bind(Int::print3,std::placeholders::_1)));

	cout<<endl;

	;

	std::for_each(vInt2.begin(),vInt2.end(),std::bind(std::plus<Int>(),std::placeholders::_1,Int(3)));
	std::for_each(vInt2.begin(),vInt2.end(),std::mem_fun_ref(&Int::print1));//如果使用非指向函数名的指针,会报错
	cout<<endl;

	//暂时无法使用stlmem_fun_ref实现多参数操作

	;

	std::for_each(vInt2.begin(),vInt2.end(),std::bind(std::mem_fun_ref(&Int::addNum),std::placeholders::_1,3));
	std::for_each(vInt2.begin(),vInt2.end(),std::mem_fun_ref(&Int::print1));//如果使用非指向函数名的指针,会报错
	cout<<endl;

	std::istream_iterator<int> in_it(cin),eos;//这里有个bug,必须要用多线程解决。程序主线程启动读写,等待输入操作中断置位,vs_stl不提供切换操作。MS的STL中insert_iterator采用主动读取数据的操作,主线程将中断读取操作中。这会导致一个严重的bug,即构建某个IO操作时提前完成了数据操作,而这可能不是我们期望的。

	std::function<bool(int)> f1 = std::bind(std::less<int>(),std::placeholders::_1,13);

	cout<<"less(3,13):"<<f1(3)<<endl;

	while (!(in_it==eos))
	{
		cout<<*in_it;
		cout<<endl;
		++in_it;
	}

	return 0;
}

时间: 2024-08-02 16:52:40

gnu编译C++11,最好与win32公用代码的相关文章

Windows平台编译libiconv-1.11库(32位、64位)

从http://download.csdn.net/detail/pony12/7789079下载libiconv-1.11.1.tar.gz源代码. 一.编译win64位 0.转移到命令行cmd 1.执行amd64位脚本,D:\Program Files (x86)\Microsoft Visual Studio 8\VC\bin\amd64\vcvarsamd64.bat 2.转移到libiconv-1.11.1目录 3.编译nmake -f Makefile.msvc  DLL=1  MF

[转载]Linux 环境下编译 0.11版本内核 kernel

最近在看<linux内 核0.11完全注释>一书,由于书中涉及汇编语言的地方众多,本人在大学时汇编语言学得一塌糊涂,所以实在看不下去了,头都大了只好匆匆看了个头尾(前面 几章和最后一章).看来即使有<九阴真经>这样的武功秘籍,内功不够也是修炼不出来神马来的.于是索性下了个0.11版本的kernel下来尝试编译一 把. linux-0.11.tar.gz 下载地址: 下面开始工作: 1. tar xvfz linux-0.11.tar.gz 2. cd linux-0.11 3. m

SewerCAD.V8i.v08.11.05.113.Win32 1CD+HAMMER.XM.v08.09

Bentley.SewerCAD.V8i.v08.11.05.113.Win32 1CD Bentley系列: Bentley AXSYS.Engine XM Edition.v08.09.03.53 Bentley AXSYS.Integrity XM Edition.v08.09.03.53 Bentley AXSYS.Process XM Edition.v08.09.03.53 Bentley.HAMMER.XM.v08.09.400.34 Bentley.PlantWise.XM.v8

gcc6.3编译c++11的程序链接opencv时字符型函数未定义

在Windows下编写图像处理程序,由于要使用regex,升级了mingw,编译c++11代码.之前代码中使用了opencv2.4.10,一直运行良好,升级编译器以后发现了错误:undefined reference to `cv::imread(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'原因:If you get li

VS2012通过makefile编译OpenGL红宝书的示例代码

> 通过创建新VC项目,然后设置一堆属性,对于懒人来说还是太复杂了.既然它自带了makefile,可以尝试下使用nmake. 需要注意的是VS2012的安装目录里面已经没有GL的头文件和库文件.这个改动应该在VS2010或者更早就已经采用了. 现在有了VS SDK.VS2010自动的SDK目录是C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A,更高的版本可能使用v8.0.v8.0A,反正都在这个目录下面.这个目录下面有include.lib文

SVN 外部引用(svn:externals)处理相似系统的公用代码

我们常常遇到这样一个场景,我们有两个系统,两个系统用的是同一套框架.如果我们用两套程序 去做,当我们修改这个公共的框架的时候,另外一个还是旧版本的,很容易造成混乱. SVN的外部用就是处理这种情况的. 我们有一个系统A,一个系统B.我们将它们公用的文件提取出来,作为系统C,由独立一个SVN版本管理库.然后A和B系统分别引用C.这样,无论在A还是B系统上修改和获取,都能够同步到最新的C代码. 设置外部引用目录的方式如下: 这样就可以了,除了这样,项目所有的代码都会提交到主URL,除了这个“公用代码

前端与编译原理 用js去运行js代码 js2run

# 前端与编译原理 用js去运行js代码 js2run 前端与编译原理似乎相隔甚远,各种热门的框架都学不过来,那能顾及到这么多底层呢,前端开发者们似乎对编译原理的影响仅仅是"抽象语法树",但这只是个开头而已,我们的目的是利用js直接运行js代码 项目地址 安装及使用方法 写这个干嘛,有现成的eval不香么 接触过微信小程序开发的同学或许知道,小程序为运行环境禁止new Function,eval,setTimeout等方法的使用,限制了我们执行字符串形式的动态代码,其他小程序平台对此也

GNU编译工具链介绍---Antoconf

大家在下载很多自由软件的源码下来编译的时候,都要用到configure这个命令,然后make,make install等等,这里我们就浅显地介绍一下什么是autoconf: 1. 基本介绍 autoconf就是一个生成shell脚本(或者其他操作系统上的可解释脚本或程序)的程序,生成的shell脚本用来根据所在的编译环境对源码进行配置.举个很简单的例子,比如我在Linux和Mac上面编译同样一份源码,编译出的程序可能一个显示Linux版本信息,一个显示Mac的版本信息,这就是autoconf起到

g++编译C++11/C++0x遇到的问题

在看<Cplusplus Concurrency In Action Practical Multithreading>时遇到第一个例子: #include<iostream> #include<thread> void hello() { std::cout<<"hello concurrent world\n"; } int main() { std::thread t(hello); t.join(); } 我安装了g++-4.8版