Difference between revisions of "C++11 in Hall D Online"

From GlueXWiki
Jump to: navigation, search
m
m
Line 97: Line 97:
 
No more contortions to statically initialize map elements and other variables.
 
No more contortions to statically initialize map elements and other variables.
  
 +
struct Object {
 +
    float first;
 +
    int second;
 +
};
 +
Object anArray[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; // initialize array of three Objects
  
  
Line 103: Line 108:
 
Now a constructor can invoke another constructor in the same class.
 
Now a constructor can invoke another constructor in the same class.
  
 +
class SomeType  {
 +
    int number;
 +
 
 +
public:
 +
    SomeType(int new_number) : number(new_number) {}
 +
    SomeType() : SomeType(42) {}
 +
};
  
  

Revision as of 10:57, 16 July 2013

Below I list a number of new C++11 features that should be interesting for use in the Hall D Online.

The most important ones concern programming safety, i.e. they plug safety loopholes in C++ that have been there since the beginning. The second type concern programming convenience, i.e. they make the code easier to write and understand.

Although we do not have any hard-and-fast programming rules for the online, I strongly feel the safety features should be used in all new code. I recommend use of the convenience features, but this is a personal decision. Even if you don't use them you should be familiar with them since they will appear in online code written by others.

Note that I take it for granted the old C++98 features will be used regularly (e.g. templates, the STL, etc).

My discussion below is brief. For a comprehensive discussion of C++11 see the Wikipedia article on C++11. See also the article on Ten C++11 Features Every C++ Developer Should Use.


Safety

Override

You can explicitly mark a method to override a base class method. If no base class method with the same signature exists a compiler error is generated. This can save you much grief, trust me.

class Derived : Base {
    virtual void some_func(int) override;  // just use the keyword, it never hurts
}


nullptr

NULL is replaced by the typed nullptr constant. The former is just a macro that gets replaced by 0 and its use is bug-prone, the latter actually has a special type.

cMsg *x = nullptr;   // don't use NULL


Static Assert and Type Traits

You can make compile time assertions about the code, e.g. that some constant expression is positive. A compiler warning is generated if it's not true. Using this along with type traits in templates allows you to make compile time assertions about variable types when templates are instantiated. E.g. you can assert that a template type is numeric and generate an error at compile time when someone instantiates your template using string or other non-numerical types.

static_assert((GREEKPI > 3.14) && (GREEKPI < 3.15), "GREEKPI is inaccurate!");
template<class Integral> Integral foo(Integral x, Integral y) {
   static_assert(std::is_integral<Integral>::value, "foo() parameter must be an integral type.");
}


Smart Pointers

Studies show that memory leaks and pointer errors comprise the majority of errors in C++ code. The former are particularly important for code that runs 24x7, such as in online systems. The use of smart pointers should mostly eliminate these errors. Smart pointers are objects that wrap bare pointers and make sure the underlying object is deleted when it is no longer needed. There are extensive discussions concerning the use of smart pointers on the web. Most important are unique_ptr<> and shared_ptr<>.

std::unique_ptr<int> p1(new int(5));   // choice depends on intended usage and who manages memory
std::shared_ptr<int> p1(new int(5));


Move Semantics

Many errors and inefficiencies occur due to copy construction, often when it is not even needed. The new move sematics allows for transfer of objects between modules without copying, and with simpler syntax. See Johann's slides for details.


Deleted and Defaulted Methods

You can tell the compiler to auto-generate certain methods, or tell it NOT to do so (e.g. copy constructor, operator=). Sometimes auto-generated versions don't do what you want, or you may not want it to exist at all.

class SomeType {
   SomeType() = default;  // The default constructor is explicitly stated.
};
class NoInt {
   void f(int) = delete;   // no silent cast to int from double, float, etc. allowed
};
class NonCopyable {
   NonCopyable() = default;
   NonCopyable(const NonCopyable&) = delete;
   NonCopyable & operator=(const NonCopyable&) = delete;
};


Convenience

auto

Much typing can be avoided by letting the compiler figure out the type of a variable from its context.

auto other_variable = 5;
for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr) {  }


Range-For

This is like "foreach" in scripting languages. Coupled with "auto" it becomes much simple to code iterations over all elements in a container.

int my_array[5] = {1, 2, 3, 4, 5};
for (auto x : my_array) {
   cout << x << endl;
}

Initializer Lists

No more contortions to statically initialize map elements and other variables.

struct Object {
   float first;
   int second;
};
Object anArray[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; // initialize array of three Objects


Delegating Constructors

Now a constructor can invoke another constructor in the same class.

class SomeType  {
   int number;
 
public:
   SomeType(int new_number) : number(new_number) {}
   SomeType() : SomeType(42) {}
};


Thread Library

Improved functionality and better API compared to the old pthread C library.


Lambdas

New way to define inline functions, eliminates need to declare and define functions.


Tuples

Generalization of "pair" to more than two variables, don't need to create special structs.


New Algorithms

Many new algorithms, always check the list before coding up basic operations on containers.


Regular Expression Facility

Soon to be available, similar to what exists in Python, Perl and Java.