Click here to Skip to main content
12,354,998 members (64,190 online)
Click here to Skip to main content
Add your own
alternative version

Stats

41.4K views
36 bookmarked
Posted

C++ 11 features in Visual C++ 2013 Preview

, 21 Jul 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
This is a quick overview of ISO C++ 11 compiler features that are supported in VC++ 2013 Preview

Introduction

When Visual C++ 2013 Preview was released in the last week of June, C++ developers were pleased to find that the compiler has added support for several ISO C++ 11 features. This article is an assemblage of those new features and includes code snippet examples that show the new features in action. You will need to download and install Visual Studio2013 Preview if you want to compile the examples in this article. I have not tested the examples on any other compiler, so I do not know how compatible it would be with GCC or Clang.

Raw string literals

VC++ 2013 now supports raw string literals. Note that it does not support Unicode string literals. A raw string literal allows you to avoid having to escape special characters which can be handy with HTML, XML, and regular expressions. Here's an example usage.

auto s1 = R"(This is a "raw" string)";

Now s1 is a const char* containing the value - This is a "raw" string. It's similar to the @ string literal support in C# although even that does not support embedded double quotes. So, what if you want to embed R"(...)" in a string literal. In that case, you can use the following syntax.

auto s2 = R"QQ(Example: R"(This is my raw string)")QQ";

Now s2 contains - Example: R"(This is my raw string)". In this example, I've used QQ as a delimiter. This delimiter can be any string up to 16 characters in length. Raw string literals can contain newlines too.

auto s3 = R"(<tr>
<td>data</td>
</tr>)";

Eventually, whenever they add support for Unicode string literals as well, you will be able to combine them and have raw Unicode string literals.

Variadic templates

Variadic templates are templates that can take a variable number of template arguments. In my opinion, it's more a feature for library authors than for library consumers, so I am not sure how popular its use will be among end-user C++ developers. Here's a very simple example that shows variadic templates in action.

// Variadic template declaration
template<typename... Args> class Test;

// Specialization 1
template<typename T> class Test<T>
{
public:
  T Data;
};

// Specialization 2
template<typename T1, typename T2> class Test<T1, T2>
{
public:
  T1 Left;
  T2 Right;
};

void Foo()
{
  Test<int> data;
  data.Data = 24;

  Test<int, int> twovalues;
  twovalues.Left = 12;
  twovalues.Right = 15;
}

The intellisense kicks in and works beautifully too when using variadic templates. The implementation of variadic templates includes a sizeof... operator that returns the number of template arguments in the parameter pack.

template<typename... Args> class Test
{
public:
  size_t GetTCount()
  {
    return sizeof...(Args);
  }
};

// . . .

Test<int> data;
size_t args = data.GetTCount(); //1

Test<int, int, char*> data2;
args = data2.GetTCount(); //3

Test<int, float> data3;
args = data3.GetTCount(); //2

It's really more of a count-of here but I guess they chose to reuse an existing operator that's familiar to C++ developers.

A typical approach used with variadic templates is to specialize it for one argument with the rest of the arguments being optional (which works recursively). Here's a rather naïve example which is probably an example of how not to use variadic templates, but it helped me understand variadic templates better.

template<typename... Args> class Test;

// Specialization for 0 arguments
template<> class Test<>
{
};

// Specialization for at least 1 argument

template<typename T1, typename... TRest> class Test<T1, TRest...> 
  : public Test<TRest...>
{
public:
  T1 Data;

  // This will return the base type
  Test<TRest...>& Rest() 
  {
    return *this;
  }
};

void Foo()
{
  Test<int> data;
  data.Data = 24;

  Test<int, int> twovalues;
  twovalues.Data = 10;
  // Rest() returns Test<int>
  twovalues.Rest().Data = 11;

  Test<int, int, char*> threevalues;
  threevalues.Data = 1;
  // Rest() returns Test<int, int>
  threevalues.Rest().Data = 2;
  // Rest().Rest() returns Test<char*>
  threevalues.Rest().Rest().Data = "test data";
}

Please be aware that no one ever writes code like this. This example was merely for academic purposes. There are correct ways to do this as I show in the next section.

Tuple implementation

I took a look at the std tuple header file (maintained by Stephan T. Lavavej of the VC++ team - original code by P.J. Plauger) and it would be an understatement to say that my head was spinning for a while just going through the code. To understand better how it was implemented, I simplified it down and extracted out the minimal code required to instantiate a tuple and to access its values (and be able to both read and write). It helped me understand how variadic templates are typically used with recursive expansion to significantly reduce lines of code when designing template classes.

// tuple 
template<class... _Types> class tuple;

// empty tuple
template<> class tuple<> {};

// recursive tuple definition
template<class _This,
  class... _Rest>
  class tuple<_This, _Rest...>
  : private tuple<_Rest...>
{ 
public:
  _This _Myfirst;
};

The recursive specialization uses inheritance so that we'll end up with members for every argument type specified for the tuple. To access a tuple value, a tuple_element class is used as a sort of accessor class.

// tuple_element
template<size_t _Index, class _Tuple> struct tuple_element;

// select first element
template<class _This, class... _Rest>
struct tuple_element<0, tuple<_This, _Rest...>>
{
  typedef _This& type;
  typedef tuple<_This, _Rest...> _Ttype;
};

// recursive tuple_element definition
template <size_t _Index, class _This, class... _Rest>
struct tuple_element<_Index, tuple<_This, _Rest...>>
  : public tuple_element<_Index - 1, tuple<_Rest...> >
{ 
};

Again, recursive inheritance is used, and the 0th case is specialized as well. Notice the two typedefs, one of them is a reference to the type of the value, and the other represents the tuple with the same arguments as the tuple_element . So, given an _Index value, we can retrieve the type of the tuple and the type of the tuple value for that recursion level. This is used in the get method.

// get reference to _Index element of tuple
template<size_t _Index, class... _Types> inline
  typename tuple_element<_Index, tuple<_Types...>>::type
  get(tuple<_Types...>& _Tuple)
{
  typedef typename tuple_element<_Index, tuple<_Types...>>::_Ttype _Ttype;
  return (((_Ttype&) _Tuple)._Myfirst);
}

Notice the return type, it uses the type typedef defined above. Similarly, the tuple is cast to the _TType typedef defined above and then we access the _Myfirst member (which represents the value). Now you can write code as follows.

tuple<int, char> t1;
get<0>(t1) = 959;
get<1>(t1) = 'A';

auto v1 = get<0>(t1);
auto v2 = get<1>(t1);

Now, this goes without saying, but I'll say it just to be sure - but this is just for demonstration. Do not use this in production code, instead use std::tuple which does all this and lots more (there's a reason it's 800 lines long).

Delegating constructors

This is something C# has had for ages, so it is great to finally get it in C++ too. The compiler feature allows a type's constructor (the delegating constructor) to have another constructor of the type in its initialization list. So when you previously had to write code like this.

class Error
{
public:
  Error()
  {
    Init(0, "Success");
  }

  Error(const char* message)
  {
    Init(-1, message);
  }

  Error(int errorCode, const char* message)
  {
    Init(errorCode, message);
  }

private:
  void Init(int errorCode, const char* message)
  {
    //...
  }
};

With delegating constructors, you can now write it as following.

class Error
{
public:
  Error() : Error(0, "Success")
  {
  }

  Error(const char* message) : Error(-1, message)
  {
  }

  Error(int errorCode, const char* message)
  {
    // ...
  }
};

Bonus reading - Here's a humorous article written 10 years ago (May 2003) by Herb Sutter and Jim Hyslop on delegating constructors, way before the standards body started considering it as a serious proposal.

Default template arguments for function templates

This is yet another C++ 11 feature that's now supported in VC++ 2013. Until now, the following code would not compile with VC++.

template <typename T = int> void Foo(T t = 0) { }

// error C4519: default template arguments are only 
// allowed on a class template

Visual C++ 2013 compiles this fine, and the template type is inferred correctly.

Foo(12L); // Foo<long>
Foo(12.1); // Foo<double>
Foo('A'); // Foo<char>
Foo(); // Foo<int>

The usefulness of this feature is more evident in the following example.

template <typename T> class Manager 
{
public:
  void Process(T t) { }
};

template <typename T> class AltManager
{
public:
  void Process(T t) { }
};

template <typename T, typename M = Manager<T>> void Manage(T t)
{
  M m;
  m.Process(t);
}

Manage(25); // Manage<int, Manager<int>>
Manage<int, AltManager<int>>(25); // Manage<int, AltManager<int>>

Not all arguments need to have defaults.

template <typename B, typename T = int> void Bar(B b = 0, T t = 0) { }

Bar(10); // Bar<int, int>
Bar(10L); // Bar<long, int>
Bar(10L, 20L); // Bar<long, long>
Bar(); // will not compile

When you have overloaded function templates with default arguments, you can run into compiler errors when the type cannot be inferred.

template <typename T = int> void Foo(T t = 0) { }
template <typename B, typename T = int> void Foo(B b = 0, T t = 0) { }

Foo(12L); // will not compile
Foo(12.1); // will not compile
Foo('A'); // will not compile
Foo(); // Foo<int>

So, that's one thing to watch out for when using default template arguments with function templates.

Explicit conversion operators

I remember a rather embarrassing day in August 2004 when I realized that despite considering myself to be a decent C++ programmer, I had not until then known about the explicit keyword. I have a blog entry from back then.

Just to summarize the use of explicit, consider the example below.

class Test1
{
public:
  explicit Test1(int) { }
};

void Foo()
{
  Test1 t1(20);
  Test1 t2 = 20; // will not compile
}

While this could be done with conversion constructors, there was no way to do this for conversion operators because the standard did not support it. The bad thing about this was that you could not design a class to have consistency between conversion constructors and conversion operators. Consider the example below.

class Test1
{
public:
  explicit Test1(int) { }
};

class Test2
{
  int x;
public:
  Test2(int i) : x(i) { }
  operator Test1() { return Test1(x); }
};

void Foo()
{
  Test2 t1 = 20;
  Test1 t2 = t1; // will compile
}

That compiles now. Well, with C++ 11, you can now apply explicit on your conversion operators too.

class Test2
{
  int x;
public:
  Test2(int i) : x(i) { }
  explicit operator Test1() { return Test1(x); }
};

void Foo()
{
  Test2 t1 = 20;
  Test1 t2 = (Test1)t1; // this compiles
  Test1 t3 = t1; // will not compile
}

Here's a not so obvious behavior with bool conversion operators.

class Test3
{
public:
  operator bool() { return true; }
};

void Foo()
{
  Test3 t3;
  if (t3)
  {
  }

  bool b = t3;
}

That compiles fine. Now try adding explicit to the operator.

class Test3
{
public:
  explicit operator bool() { return true; }
};

void Foo()
{
  Test3 t3;
  if (t3) // this compiles!
  {
  }

  bool b = t3; // will not compile
}

As expected, the 2nd conversion failed to compile, but the first one did. That's because the if construct's bool conversion is treated as explicit. So you need to be wary of this, just adding explicit to your bool conversion operator will not keep your type safe from accidental conversions to bool.

Initializer lists and uniform initialization

We've always been able to use initializer lists with arrays, now you can do it with any type that has a method that takes an argument of type std::initializer_list<T> (including constructors). The standard library collections have all been updated to support initializer lists.

void foo()
{
  vector<int> vecint = { 3, 5, 19, 2 };
  map<int, double> mapintdoub =
  {
    { 4, 2.3},
    { 12, 4.1 },
    { 6, 0.7 }
  };
}

And it's trivial to do this with your own functions.

void bar1(const initializer_list<int>& nums) 
{
  for (auto i : nums)
  {
    // use i
  }
}

bar1({ 1, 4, 6 });

You can also do it with your user defined types.

class bar2
{
public:
  bar2(initializer_list<int> nums) { }
};

class bar3
{
public:
  bar3(initializer_list<bar2> items) { }
};

bar2 b2 = { 3, 7, 88 };

bar3 b3 = { {1, 2}, { 14 }, { 11, 8 } };

Uniform initialization is a related feature that's been added to C++ 11. It automatically uses the matching constructor.

class bar4
{
  int x;
  double y;
  string z;

public:
  bar4(int, double, string) { }
};

class bar5
{
public:
  bar5(int, bar4) { }
};

bar4 b4 { 12, 14.3, "apples" };

bar5 b5 { 10, { 1, 2.1, "bananas" } };

If there's an initializer-list constructor, it takes precedence over another matching constructor.

class bar6
{
public:
  bar6(int, int) // (1)
  {
    // ...
  }

  bar6(initializer_list<int>) // (2)
  {
    // ...
  }
};
  
bar6 b6 { 10, 10 }; // --> calls (2) above

Alright, that's it. As usual, feedback and criticism are very welcome. Thank you.

References

History

  • July 20th, 2013 - Article published

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Nish Nishant
United States United States
Nish Nishant is a Software Architect/Consultant based out of Columbus, Ohio. He has over 16 years of software industry experience in various roles including Lead Software Architect, Principal Software Engineer, and Product Manager. Nish is a recipient of the annual Microsoft Visual C++ MVP Award since 2002 (14 consecutive awards as of 2015).

Nish is an industry acknowledged expert in the Microsoft technology stack. He authored
C++/CLI in Action for Manning Publications in 2005, and had previously co-authored
Extending MFC Applications with the .NET Framework for Addison Wesley in 2003. In addition, he has over 140 published technology articles on CodeProject.com and another 250+ blog articles on his
WordPress blog. Nish is vastly experienced in team management, mentoring teams, and directing all stages of software development.

Contact Nish : You can reach Nish on his google email id voidnish.

Website and Blog

You may also be interested in...

Comments and Discussions

 
Questionc Pin
Cliff Flax27-Feb-14 5:24
memberCliff Flax27-Feb-14 5:24 
Questioncrawling to C# Pin
Majid Shahabfar29-Aug-13 9:05
memberMajid Shahabfar29-Aug-13 9:05 
QuestionNicely done Pin
H.Brydon27-Jul-13 15:49
memberH.Brydon27-Jul-13 15:49 
AnswerRe: Nicely done Pin
Nish Sivakumar30-Jul-13 2:47
sitebuilderNish Sivakumar30-Jul-13 2:47 
GeneralMy vote of 5 Pin
Wong Shao Voon24-Jul-13 19:52
memberWong Shao Voon24-Jul-13 19:52 
GeneralRe: My vote of 5 Pin
Nish Sivakumar25-Jul-13 2:15
sitebuilderNish Sivakumar25-Jul-13 2:15 
QuestionI'd like to see real-worl example of Variadic Templates. Pin
Maximilien24-Jul-13 3:58
memberMaximilien24-Jul-13 3:58 
AnswerRe: I'd like to see real-worl example of Variadic Templates. Pin
Nish Sivakumar24-Jul-13 3:59
sitebuilderNish Sivakumar24-Jul-13 3:59 
GeneralRe: I'd like to see real-worl example of Variadic Templates. Pin
Supreme Master16-Oct-13 1:22
memberSupreme Master16-Oct-13 1:22 
GeneralMy vote of 5 Pin
Member 996927122-Jul-13 19:14
memberMember 996927122-Jul-13 19:14 
GeneralRe: My vote of 5 Pin
Nish Sivakumar23-Jul-13 1:44
sitebuilderNish Sivakumar23-Jul-13 1:44 
GeneralMy vote of 5 Pin
WolfieH22-Jul-13 11:23
memberWolfieH22-Jul-13 11:23 
GeneralRe: My vote of 5 Pin
Nish Sivakumar22-Jul-13 12:55
sitebuilderNish Sivakumar22-Jul-13 12:55 
GeneralMy vote of 5 Pin
TerranceSmith22-Jul-13 7:20
memberTerranceSmith22-Jul-13 7:20 
GeneralRe: My vote of 5 Pin
Nish Sivakumar22-Jul-13 12:54
sitebuilderNish Sivakumar22-Jul-13 12:54 
GeneralMy vote of 5 Pin
John Schroedl22-Jul-13 5:42
memberJohn Schroedl22-Jul-13 5:42 
GeneralRe: My vote of 5 Pin
Nish Sivakumar22-Jul-13 12:54
sitebuilderNish Sivakumar22-Jul-13 12:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160621.1 | Last Updated 21 Jul 2013
Article Copyright 2013 by Nish Nishant
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid