C++博客-天秤座的唐风-最新评论http://www.cppblog.com/liyiwen/CommentsRSS.aspx总会有一个人需要你的分享~!- 唐风 -zh-cnMon, 14 Dec 2009 03:16:00 GMTMon, 14 Dec 2009 03:16:00 GMTcnblogsre: C++中的类型擦除(type erasure in c++)http://www.cppblog.com/liyiwen/archive/2009/12/14/102950.html#103167Vitacy.TanVitacy.TanMon, 14 Dec 2009 03:16:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/14/102950.html#103167参数个数 类型 还有像int a(int b=1);
在C++里参数个数 类型在函数名里(指针好像也没这个),默认参数可以重载解决


Vitacy.Tan 2009-12-14 11:16 发表评论
]]>
re: C++中的类型擦除(type erasure in c++)http://www.cppblog.com/liyiwen/archive/2009/12/13/102950.html#103092唐风唐风Sun, 13 Dec 2009 04:05:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/13/102950.html#103092话又说回来,在你的做法中,并没有直接在 function pointer 和 void* 之间进行转型,而是为 function pointer 创建(new)了一个对象,赋给 void*,这样做我感觉是没有问题的,这时候 void* 指向的仍然是一个“对象”,呵呵。
但这么做可能在“效率”上不如直接备份 function pointer 。毕竟,创建时候的 new 和调用时的转型加最后的 delete,都比直接存 function pointer 负担大。但这样做获得了代码上的一致性,我倒是挺喜欢的,呵呵(如果确实没有“我所不知道的问题的话”)。


唐风 2009-12-13 12:05 发表评论
]]>
re: C++中的类型擦除(type erasure in c++)http://www.cppblog.com/liyiwen/archive/2009/12/13/102950.html#103090唐风唐风Sun, 13 Dec 2009 03:53:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/13/102950.html#103090在网上找了一下相关的资料,发现这个问题其实已经有了比较多的“讨论”,还有专门论述的文章:
http://www.safercode.com/blog/2008/11/25/generic-function-pointers-in-c-and-void.html

简而言之,就是:
不能 void* 和 void(*f)() 合并成一个,原因是对于 C 标准而言,这两个“东西”并不保证一致,函数指针的大小可能比 void* (也就是指向数据的指针大小要大),可能会包含更多的信息,如果在这之间进行转换的话,在某些平台会产生未定义的行为(在 Windows 平台下,这样做是没问题的,参考http://stackoverflow.com/questions/1867698/casting-a-void-pointer-data-to-a-function-pointer 中的回复)。因此,这么做是为了可移植性的考虑。

相关原文如下:
Why can’t we use void* for a Generic Function Pointer?
This is because a void* is a pointer to a generic “data” type. A void * is used to denote pointers to objects and in some systems, pointers to functions can be larger than pointers to objects. So, if you convert amongst them, you’ll lose information and hence, the situation would be undefined and implementation dependent. Most compilers won’t even warn you if you convert between them but some might error out, if you try to call such a void * to function pointer converted. But even they might fail to alert you, if you take care of typecasting the call perfectly (Enclose in parentheses before function call brackets). And then, one fine day, you’ll try to compile and run your program on one of the aforementioned systems, and then keep on wondering why your program segfaults.

Note: C++ does allow this “conditionally” which means that such a conversion is allowed but a compiler is not bound to implement this feature, which again makes its usage circumspect.

另外,我还是不太明白,function pointer 可能携带的其它信息是什么,呵呵,再查查喽。

谢谢 Vitacy.Tan 的回复,让我能更深入的了解这方面的知识。
嗯,有人能参与讨论就是好啊,希望大家多指点。





唐风 2009-12-13 11:53 发表评论
]]>
re: C++中的类型擦除(type erasure in c++)http://www.cppblog.com/liyiwen/archive/2009/12/12/102950.html#103032唐风唐风Sat, 12 Dec 2009 02:50:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/12/102950.html#103032@Vitacy.Tan
嗯,试过了你的代码,确实在我的例子的情况下,你的做法没有问题而且更简洁。呵,说真的,第一次看到 new 一个 function pointer 对象,有点诧异。后来想通了,function pointer 也不过就是一个 pointer 而已。
但 boost::function 中确实对两者进行了区分对待,而且考虑了更多的情况情况:
/**
       * A buffer used to store small function objects in
       * boost::function. It is a union containing function pointers,
       * object pointers, and a structure that resembles a bound
       * member function pointer.
       
*/

      union function_buffer
      
{
        
// For pointers to function objects
        mutable void* obj_ptr;

        
// For pointers to std::type_info objects
        struct type_t {
          
// (get_functor_type_tag, check_functor_type_tag).
          const BOOST_FUNCTION_STD_NS::type_info* type;

          
// Whether the type is const-qualified.
          bool const_qualified;
          
// Whether the type is volatile-qualified.
          bool volatile_qualified;
        }
 type;

        
// For function pointers of all kinds
        mutable void (*func_ptr)();

        
// For bound member pointers
        struct bound_memfunc_ptr_t {
          
void (X::*memfunc_ptr)(int);
          
void* obj_ptr;
        }
 bound_memfunc_ptr;

        
// For references to function objects. We explicitly keep
        
// track of the cv-qualifiers on the object referenced.
        struct obj_ref_t {
          mutable 
void* obj_ptr;
          
bool is_const_qualified;
          
bool is_volatile_qualified;
        }
 obj_ref;

        
// To relax aliasing constraints
        mutable char data;
      }
;

在下浅薄,不能完全明白其中的道理,还请路过高人指点。
 

 


唐风 2009-12-12 10:50 发表评论
]]>
re: C++中的类型擦除(type erasure in c++)http://www.cppblog.com/liyiwen/archive/2009/12/11/102950.html#102972Vitacy.TanVitacy.TanFri, 11 Dec 2009 05:21:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/11/102950.html#102972 void (*fun_prt) (); // 函数指针
void * fun_obj; // 函数对象
};
不用分开对待,直接void * fun就行了.函数可以直接当对象使用.
template <typename R,typename F>
class callable
{
public:
static R call(void * fun){
return (*static_cast<F *>(fun))();
}
static void destory(void *fun){
delete static_cast<F*>(fun);
}
};
template <typename R>
class function
{
public:
R operator () (){
return (*m_call)(m_fun);
}
template <typename T>
void operator=(T fun){
m_fun = static_cast<void *>(new T(fun));
m_call=callable<R,T>::call;
m_destory=callable<R,T>::destory;
}
template <typename T>
R call(){
(*static_cast<T *>(m_fun))();
}
~function(){
(*m_destory)(m_fun);
}
private:
void * m_fun;
R (*m_call)(void *);
void (*m_destory)(void *);
};


Vitacy.Tan 2009-12-11 13:21 发表评论
]]>
re: C++中的类型擦除(type erasure in c++)http://www.cppblog.com/liyiwen/archive/2009/12/11/102950.html#102958崇文崇文Fri, 11 Dec 2009 01:14:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/11/102950.html#102958

崇文 2009-12-11 09:14 发表评论
]]>
re: C++中的类型擦除(type erasure in c++)http://www.cppblog.com/liyiwen/archive/2009/12/11/102950.html#102956TouchsoftTouchsoftFri, 11 Dec 2009 01:00:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/11/102950.html#102956

Touchsoft 2009-12-11 09:00 发表评论
]]>
re: 与临时对象的斗争(下)http://www.cppblog.com/liyiwen/archive/2009/12/08/102496.html#102807唐风唐风Tue, 08 Dec 2009 10:15:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/08/102496.html#102807好吧,我只能说,是你自己在 cppblog 的链接中列出来的。哈哈哈哈 :P
阁下爱好很广嘛,编译原理狂人(别人这么叫你的) + 漫迷 ……

嗯嗯,凡有回复必回访是我的原则,哈哈,也是想通这这种途径了解对方,多交些朋友





唐风 2009-12-08 18:15 发表评论
]]>
re: 与临时对象的斗争(下)http://www.cppblog.com/liyiwen/archive/2009/12/08/102496.html#102801陈梓瀚(vczh)陈梓瀚(vczh)Tue, 08 Dec 2009 08:50:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/08/102496.html#102801

陈梓瀚(vczh) 2009-12-08 16:50 发表评论
]]>
re: 与临时对象的斗争(下)http://www.cppblog.com/liyiwen/archive/2009/12/07/102496.html#102740唐风唐风Mon, 07 Dec 2009 11:24:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/07/102496.html#102740确实如你所言。谢谢你的回复。

说实话,“并行计算”这种高级货,我还真没玩过,嘿嘿。

嗯嗯,真心求教:
这方面有没有比较好的已经成熟的做法(库?)?能不能介绍一下?如果一个表达式比较复杂(比如有加减乘、有括号之类)有什么算法能正确地最优地根据可以并行的“行程”数来分配计算子过程?各子过程的之间的“通信”是怎么做的呢?会像一般“多线程”中的锁机制那样吗(当然,我对锁这东西的理解也限于“理论”范畴内,呵呵)?

PS:
刚才回访了你的 blog,里面大多都是算法方面的东西啊,呵呵。向你学习 :D






唐风 2009-12-07 19:24 发表评论
]]>
re: 与临时对象的斗争(下)http://www.cppblog.com/liyiwen/archive/2009/12/07/102496.html#102707Wang FengWang FengMon, 07 Dec 2009 03:36:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/07/102496.html#102707如果可以并行的话,这样很有优势
ans = ((a+b)+(c+d))+((e+f)+(g+h));
你这个+=虽然省去了一些临时对象,不过也只好一个一个乖乖地+=了,单个cpu的时候没有事情,多个cpu的时候,大好时间都浪费了。

Wang Feng 2009-12-07 11:36 发表评论
]]>
re: 与临时对象的斗争(上)http://www.cppblog.com/liyiwen/archive/2009/12/06/102417.html#102667唐风唐风Sun, 06 Dec 2009 14:25:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/06/102417.html#102667你也注册一个博客园(或是cppblog)的帐户呗
对评论和回复有邮件通知,这个功能挺好用的。

唐风 2009-12-06 22:25 发表评论
]]>
re: 与临时对象的斗争(下)http://www.cppblog.com/liyiwen/archive/2009/12/04/102496.html#102563唐风唐风Fri, 04 Dec 2009 10:51:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/04/102496.html#102563
operation proxy……

好形象啊,哈哈
你上篇的回复里就说到了这个呢,不过我是事后才认识到……:P



唐风 2009-12-04 18:51 发表评论
]]>
re: 与临时对象的斗争(下)http://www.cppblog.com/liyiwen/archive/2009/12/04/102496.html#102562唐风唐风Fri, 04 Dec 2009 10:49:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/04/102496.html#102562谢谢老大支持!!

配合内联 RVO,很多情况下这些临时小对象也可以消失,你看看我上面回复中给的链接,MS 有说明……

至于不习惯模板,嘿嘿,吐啊吐啊就习惯了。:)



唐风 2009-12-04 18:49 发表评论
]]>
re: 与临时对象的斗争(下)http://www.cppblog.com/liyiwen/archive/2009/12/04/102496.html#102561唐风唐风Fri, 04 Dec 2009 10:41:00 GMThttp://www.cppblog.com/liyiwen/archive/2009/12/04/102496.html#102561嗯嗯,好敏锐啊,你说得很对。
d=a+(b+c);
这种在这段程序里是会产生编译错误的……

这个模板类确实非常的不完善,对于一个“可用”的ExpXXX的话,应该要是左右操作数都需要泛化的。为了进一步的重用,可以再泛化操作类型(加减乘)。

这篇文章里我想把重点放在“它可以消除临对象上”,为了能更“简单”地说明ET,所以写的例子很简陋,不过我想大概的做法已经点到了。

完善的做法比较复杂,所以我认为这个库设计都用的武器,写应用层逻辑时也许不太会用到?(调试、维护都不容易啊……)

下面有一篇文章,从头开始一点一点地完善这个ExpXXX,讲解得非常细~,每一个改善是为了什么!(不过是日文的,嘿,YESHG,为你准备的!中文英文的应该也有,不过我没搜到这么细致的,呵呵,不过对《C++templates》里的例子应该也够看了。)
http://homepage1.nifty.com/herumi/prog/prog81.html#MOTIVATION

PS:
至于那个囧类型,我还没看到有什么好的做法。因为要让左右操作数接受不同的表达式(a,a+b,a+b*c等等等等)才可用,所以操作数的“类型”不能固定,ExpPlus<I>+ExpPlus<I>==ExpPlus<I>,感觉行不通。你有什么好做法呢?



唐风 2009-12-04 18:41 发表评论
]]>