Tuesday, October 7, 2014

C++ 11 study notes(3/xx) Lvalues and Rvalues (my reference book is Bjarne's C++ and Data structure and analysis in C++)

 There are one important change in C++ 11, which is a new reference type called rvalue reference. In order to understand rvalues we must understand lvalues at first.
According to Bjarne there are 3 types of references. Which are : 
  1. lvalue references: refers to non-temporary object whose value can be changed.
  2. const references: refers to non-temporary object whose value cannot be changed.
  3. rvalue references: refers to temporary object whose value is not necessary after it has evaluated.
references
For a type T, a notation T& is used for lvalue references. General rule of lvalue is if you have a name for variable it is an lvalue. on the other hand, T&& is used for rvalue reference. General rule of rvalue is expression which is literal or expressions whose result is not set to any variable. following piece of code is the example of lvalues and rvalues.


#include <iostream>

using namespace std;

int main() {
  string str = "hi";
  string& str1 = str;   // str1 is another name for str. and lvalue
  cout << (str == str1) << endl;   // true

  string& wrong1 = "hi";   // compile error. hello is not modifiable
  string&& wrong1 = "hi";   // OK
  cout << wrong1 << endl;
  return 1;
}

Lvalue reference usages.
an lvalue references play a big role in memory savings and improve readability of source code.

USAGE 1 : aliasing names.
sometimes we need to use an object which is stored in containers like vector.
for Example:

int main() {
  .....
  std::cout << veryLongVectorName[expression that calculates the index].name << veryLongVectorName[expression that calculates the index].age << std::endl;
  return 1;
}

this program is very ugly to read. so, we can do like following.

1: int main() {
  .....
2:  SomeObject someObject = veryLongVectorName[expression that calculates the index];
3:  std::cout << someObject.name << someObject.age << std::endl
4:  return 1;
5:}

now it became easy to read(at least for me). But it has one problem which is inefficient use of memory.
expression at line 2 copies the object stored in vector to a new memory. So, if we code like following, we object will not be copied.
SomeObject& someObject = veryLongVectorName[expression that calculates the index];

Another very effective usage is in for each loops. The following loop is inefficient because it will copy every object to variable o.

for (auto o : veryLargeObjectVector) {
   .....
}

if we use use "auto & o", objects will not be copied to a new memory but just referenced by o.

Lvalue references are used to avoid a copy of function return values too. For example

VeryBigObject& veryBigObject = find(arrayOfVeryBigObject);

To summarize briefly, lvalue references are used to avoid copying objects.

Function Parameter Passing.
in briefly there are 4 parameter passing ways.
1. call-by-value
2. call-by-lvalue-reference(it can cause side-effect)
3. call-by-lvalue-reference-to-a-constant (prevent side-effect)
4. call-by-rvalue-reference
I will omit explanation of first 3 parameter passing methods, since these are old methods and writing every detail makes me boring even I write this blog to improve my English (this is why my English is so poor).









Saturday, June 14, 2014

C++ 11 study notes(2/xx) simple lambda introduction

Lambda
minimum form of lambda in C++11 is like this:

#include
using namespace std;
int main() {
[](){};
return 0;
}
and it compiles. It is just a definition of minimum lambda function.
Minimum lambda function call is like this:

[](){}();

explanation of every element is below.
first "[]" is called lambda introducer. I will write usage at the end of this entry.
second () is function arguments.
third {} is function body.
last () is lambda function call.

I will introduce simple examples below.

1. hello world in lambda is like this:

[]{std::cout << "hello lambda" << std::endl;}();
it will output string "hello lambda".

2. lambda function can be assigned to variable;

auto func = []{cout << "assign to func" << endl;};
func();

3. lambda function can be passed to another function as argument.

template
void f(Func func) {
  func();
}
f([]{cout << "pass to function as argument" << endl;});

4. passing argument to lambda function

[](string const& str){cout << str << endl;}("hah");

5. declare return type of lambda function implicitly.

  auto b = []()->float { return 3.14;}();
float is return type.

6. if we want to access local names we use lambda introducer [].

string x = "I am local string which is outside of lambda function scope";
[&](string const& str){ x += str;}(". reference capture can change value of local variable");
output will be "I am local string which is outside of lambda function scope. . reference capture can change value of local variable"
copy capture is [=].
we can specify which variable is captured by reference or copy.

int x,y,z,n;
[&, x, y]{};  //only a and b is copy capture. the others are captured by reference.
[=, &x]{};   // only x is captured by reference. the others are captured by copy.

And there was tons of features. 



  




           

C++11 study notes(1/xx)

during reading the book, I realized that I have to keep keywords and concepts in mind to continue to read book. And here is some impotant keywords from chapter6.

Chapter 6 Types and Declarations
Type category names.
Boolean, character, integer types are called integral types.
integral types and floating-point types are collectively called arithmetic types.
Enumerations + class are called user-defined types
fundamental types, pointers, references are called built-in types.

Initialization 
There are four ways to initialize a variable.
X a1{v};
X a2 = {v};
X a3 = v;
X a4(v);
The first one is new in C++11. This one do not perform the type conversion(narrowing?). and checked in compile time. Bjarne recommends this one. The other three ways are old.

classification of objects based on their lifetimes:
1. Automatic
an object declared in a function is created when its definition is encountered and destroyed when its name goes out of scope.
2. Static
Objects declared in global or namespace scope and statics declared in functions or classes are and initialized once(only) and "live" until program terminates
3. Free Store
Objects created and deleted by using the new and delete operators.
4. Temporary objects (i will complete this later)
5. Thread-local objects. (i will complete this later)

and last thing from this chapter is type alias.
in C++ there was a keyword "using" to alias the type.

1:  template<class T>  
2:  class vector {  
3:    using value_type = T;  
4:    ...  
5:  };   

Sunday, April 20, 2014

sml notes(1)

char : #"a"
val member = fn : ''a * ''a list -> ''a list
上記のように「'」が二つついている型を等値型という。
等値型  : 等値型とは、等値演算子 (=, <>) で比較できるデータ型のことです。int, real, string, bool などの基本的なデータ型は等値型です。

case 文

as 文
パターン x::xs を使うとリストを分解することができますが、分解した値 x や xs だけではなく、元のリストの値を参照したいときがあります。このような場合、as を使うと変数とパターンを同時に設定することができます。
a as x::xs と [1, 2, 3] をマッチングさせると、次のようになります。
a  -> [1, 2, 3]
x  -> 1
xs -> [2, 3]

option 型を操作する主な関数。
val getOpt : 'a option * 'a -> 'a
val isSome : 'a option -> bool
val valOf : 'a option -> 'a