Pages

About Me - 关于我

My photo
Madison, WI, United States
Joy Young ~~

2011/10/30

一个人最宝贵的六样东西

一个人最宝贵的东西是什么。很早就想过这个问题,事业?亲人?幸福?安全?自己的答案一直感觉并不是很贴切。第一次听到一个很让我信服的答案是大二那年和tx聊天,她也曾思考过这个问题,她说,是 爱,希望,和健康。
这个答案曾让我眼前一亮,那晚和她在北师散步了许久,便也把这个问题聊的通透蹭亮。甚至排了一个顺序,爱>希望>健康。本以为这便是最终的答案,然而多年以后,我竟然突然又无端的想起了这个问题。
tx无疑是正确的,但也许还有更多。
tx的答案可以作为一个基础,后来我便由此发散而去。
若是将我禁闭于某囚牢,失去自由,我宁可断腿,来换回自由。但若是有爱,和所爱且爱我的人一起,那便也没什么。若我有希望,相信有朝一日,我能重归自由,那也没有什么。所以自由,也应该排进去的,现在是爱>希望>自由>健康
还漏了什么。生命诚可贵,爱情价更高。确实,若是众叛亲离,无人爱,那不如死了。若是整日郁郁,失去希望,活着也没有意义。若是禁闭于囚牢一世,但有希望有爱,活着也挺好。所以生命可以排进来,爱>希望>生命>自由>健康。
还有什么?以前在论坛上做过一个调查,问如果把你立刻变成比尔盖茨,你愿意么?几乎没人说愿意的, 因为即使他再成功,没人愿意跳过自己40年的青春去换他的功名利禄。可见年轻竟然如此的宝贵。不过,60岁的自由生活,和20岁的囚牢生活,相信更多人会宁可过60岁的自由生活。所以年轻小于自由。如果身体不健康,20岁的体质和剩的寿命还不如60岁,那宁可选60岁,所以健康应该和年轻差不多,略大一点。所以最后我们有:
爱>希望>生命>自由>健康>年轻
就先这么多吧。

人应该定期思考下人生,不可入世太深,迷失本心,不知本我,残度聊生。

2011/04/19

TheTricky Parts of Rvalue Reference and Perfect Forwarding.

I have read two articles about these stuffs. They are good. Here are the links:
I would not like to spend much time whenever I want to look up some useful information from these two articles, so I summarize something useful for my future reference.

1. Rvalue reference is not rvalue but reference
If you try to change the value of rvalue reference, it affects the value of the object it is referencing.

2. move semantic is awesome, but not irreplaceable.

Alternatively, you can use the static_cast keyword to cast an lvalue to an rvalue reference, as shown in the following example:

int main()
{
       MemoryBlock block;
       g(block);
       g(static_cast<MemoryBlock&&>(block));//as good as move
}

3. The compiler treats a named rvalue reference as an lvalue and an unnamed rvalue 
reference as an rvalue.
void g(X&& t); // A
void g(X& t);      // B

void h(X&& t)
{
       g(t);
}

Though t is declared like rvalue reference, but it is named, so g() always treats t as lvalue. If we changed the call to g(std::move(t)) then it would always call the rvalue-reference overload.
 
4. What does std::forward do?
When T is an lvalue reference, std::forward<T> is a no-op: it just returns its argument. 
When we pass a temporary to f, so T is just plain X. In this case,  std::forward<T>(t) is equivalent to static_cast<T&&>(t): it ensures that the argument is forwarded as an rvalue reference
Note that, it does not have anything to do with t. How it works is related to T solely.
5. What does std::move do? 
 Based on my understanding alone, its function is nothing more than a static_cast<T&&>()
Here I found some evidence: 
template<typename T>
remove_reference<T>::type&& move(T&& a)
{
       return a;
}

By Jonathan Caves

Jonathan Caves - Visual C++ Compiler Team

remove_reference here is a class from boost, it removes the reference symbol & and add two more instead!

6.  Perfect forwarding is unique to template functions: we can't do this with a non-template function such as h.
To understand this, let’s see how the template deduce the parameters:
First of all, we need to write a template this way:
template <typename T> void print_type_and_value(T&& t)

The tricky part is the T&& in the function. According to different form of T, the T&& will generate different types. See:
int main()
{
      // The following call resolves to:
      // print_type_and_value<string&>(string& && t)
      // Which collapses to:
      // print_type_and_value<string&>(string& t)
      string s1("first");
      print_type_and_value(s1);

      // The following call resolves to:
      // print_type_and_value<const string&>(const string& && t)
      // Which collapses to:
      // print_type_and_value<const string&>(const string& t)
      const string s2("second");
      print_type_and_value(s2);

      // The following call resolves to:
      // print_type_and_value<string&&>(string&& t)
      print_type_and_value(string("third"));

      // The following call resolves to:
      // print_type_and_value<const string&&>(const string&& t)
      print_type_and_value(fourth());
}

The deduction rule:


Expanded type
Collapsed type
T& &
T&
T& &&
T&
T&& &
T&
T&& &&
T&&

Now let’s go back to the discussion of trying perfect forwarding in non-template function:
Within a function that takes its arguments as rvalue references, the named parameter is treated as an lvalue reference. Consequently the call to g(t) from h always calls the lvalue overload. If we changed the call to g(std::forward<X>(t)) then it would always call the rvalue-reference overload. The only way to do this with "normal" functions is to create two overloads: one for lvalues and one for rvalues.
Finally, I attached this piece of code for quick testing.

#include <iostream>
using namespace std;
struct X{int i;};
void g(X&& t){ t.i = -1; cout<<"&&"<<endl;}; // A
void g(X& t){ t.i = -2; cout<<"&"<<endl;}      // B

template<typename T>
void f(T&& t){    g(std::forward<T>(t));}
void h1(X&& t){   g(t);}
void h2(X& t){    g(std::forward<X>(t));}
void h3(X& t){    g(std::forward<X&>(t));}
void h4(X& t){    g(std::move(t));}

int main()
{
     
      X x;
      x.i = 0;
      f(x);   // 1
      f(X()); // 2
      h1(X()); // 3
      h2(x); // 3
      cout<<x.i<<endl;
      h3(x);
      cout<<x.i<<endl;
      h4(x);
      cout<<x.i<<endl;
      getchar();
}










2011/04/06

C++嵌套类

1  1. 嵌套类的名字只在外围类可见。
  2. 类的私有成员只有类的成员和友元可以访问,因此外围类不可以访问嵌套类的私有成员。嵌套类可以访问外围类的成员(通过对象、指针或者引用)。
  3.一个好的嵌套类设计:嵌套类应该设成私有。嵌套类的成员和方法可以设为 public
    4.嵌套类可以直接访问外围类的静态成员、类型名( typedef )、枚举值。
   5. 嵌套类定义的名字解析过程:
出现在名字使用点前的嵌套类的声明。
出现在名字使用点前外围类的声明。
嵌套类定义前名字空间域的声明。

 

66. 嵌套类的成员定义中的名字解析过程:
成员函数局部声明。
嵌套类成员的声明。
外围类成员的声明。
成员函数定义前名字空间域中出现的声明。

2011/04/03

哎,又想骑车去旅行了


我很懒,但是有颗不安分的心。我想过着慵懒的生活,却又不甘平凡。
保研前,一直想保研,当真发现自己能保研了,却又觉着无趣了,然后准备出国,有病是不?
懒的运动,篮球足球都不爱,因为运动量太大,太累,结果大二花了十天灰头土脸的从北京骑车600多公里回了趟家,有病是不?
美国的生活很麻烦,各种事情,各种不顺,压力很大,也没时间。自己每天回家就累的啥也不想干了,但是,突然又想骑车旅行了。
非运动型人士,骑车旅行对我来说,本应更像一个概念而非实践。不过一件事,虽然笨了点,慢了点,但只要决定去做,总还是能做成的。
上次骑了650公里。这次,如果有可能,想骑个夸张的,从东海岸骑到西海岸去。初步估计,有4500公里。以我的运动能力,大概需要40多天,才能完成。太不切实际了是么?我也觉着有点,但是,如果拿定主意去做,其实不难。我需要的仅仅是:
1.  1. 1个半月的假期
2.  2. 一两位同伴
3.  3. 10000美金
其他的,就是周详的计划,调查,问询。上回十天的旅行,做了15天计划。这回40天的旅程,也要做2个月调查计划吧。也许老美和中国不太一样,比如没自行车道,比如中部无旅馆,有野兽,但这些都不会构成根本威胁。必须的仅仅是之上3条。
哈,大学那次,从有构想,但遇到志同道合之人,到付诸实施,过了两年吧。这个构想,不知道什么时候能实现,今天就放这里了,希望34年后的某天,我会再次出发。

2011/03/31

自己的心情就是个一阶导

       事情总不会是一帆风顺的,有高潮就早晚会有低谷,vice versa, 我就是这么安慰自己的。
      人的心情是个一阶导数,无关乎你现在所处的水平,只关乎现在跟刚才的反差。
如果干净利落的一直让我凄惨着,其实也便习惯了。可惜有时候我会非常倒霉的走了下好运。然后会高兴两天。再然后呢,不过是跌回原点,但心里却又要难受半天。
是自己的早晚就是,不是的,怎么也不是。话虽这么说,当不是自己的好东西来眼前转了转又潇洒的离开时,我还是要无奈的说,行了,别涮我了。
还记得小时候看阿凡提的绝望疗法:一人抱怨房子小,阿凡提就让他塞三头牛进去住一个月。一个月后,当那人把牛全赶出去时,觉得自己的房子真是幸福无比的宽敞。
我自然没有故意这么干过,不过回头想来,以前很多觉得很高兴的时刻,无非是刚刚搞定一个自己搞砸的事,回到原点有时也能自己这么兴奋。
        前几天挂个qmd,change the unacceptable, accept the unchangable. 实验室有人当即对我说了,what if one thing is unacceptable and unchangable. 我想世上哪能有这种倒霉事。不过后来很快就发现,还是有的。所以我觉着这话正确的说法还得是,accept the unchangable, accept the unacceptable. 再难也得接受。
      Anyway,事情总是会有转机的,郁闷时就想想又为自己将来高兴提供了一次廉价的机会----我真是一个能凑合的人。
      PS: 自己的心情是一阶导,那一个对数学稍微敏感点的人自然会琢磨,什么是二阶的?周围人对你的感觉。如果你一直很低落,或者一直很兴奋,周围人早已习以为常,但倘若突然有一天一个乐天派突然很抑郁,可能便会勾起大家好奇心好好八卦一番。题外话耳

2011/03/27

发现写代码和写诗词是一样一样的

首先呢,形式接近。当然不是说近体诗。长短句,散曲,形式上看起来,错落有志,跟一段C++正常风格的代码十分类似,凹凸有型。

其次呢,都有着自己的一套非同于正常语言的语法。诗词语法上要遵循固定的格律;而代码语法上要遵循一定的标准。

再次呢,语义上也有共性。都是实际生活中的朴素的自然语言的另一种抽象,可以被interpreted成朴素的自然语言。它们本身都有着对自然语言的高度的抽象和概括,自然也都带着晦涩和怪异,也都需要一定的规则,才能实现翻译。

 然后呢,创作上,都需要一定的专门训练,都需要专业的技巧。而且技巧的高低跟创作出的质量有极大关系。

还有呢,训练上,都需要大量的阅读别人的,大牛的作品,以丰富自己的知识和技巧。只一味埋头苦练是不行的。这点我也是最近才发现。如果只自己闷头写程序,不去读一读别人的优秀开源代码,可能有些东西永远也学不到。

最后呢,好的作品都会产生美感。无论是诗词还是好的code,优美的都会让读者产生美感。

最后的最后,辩证的扯下不同点:
诗词是感性上的抽象;
代码则是理性上的抽象。

GUIDELINE

1. The explanation of the domain name:
0x7fffffff (7 f's) is the greatest positive integral value in C++ in general case; So you may consider my blog's name is meaning this. But by this name, I am also saying I'm the greatest, positive, integral man, haha. Just kidding.
2. The content of my blog. My initial thought was half English and half Chinese; half technology and half literature; half  true feelings and half casual words.