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.
template<typename... Args> class Test;
template<typename T> class Test<T>
{
public:
T Data;
};
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();
Test<int, int, char*> data2;
args = data2.GetTCount();
Test<int, float> data3;
args = data3.GetTCount();
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;
template<> class Test<>
{
};
template<typename T1, typename... TRest> class Test<T1, TRest...>
: public Test<TRest...>
{
public:
T1 Data;
Test<TRest...>& Rest()
{
return *this;
}
};
void Foo()
{
Test<int> data;
data.Data = 24;
Test<int, int> twovalues;
twovalues.Data = 10;
twovalues.Rest().Data = 11;
Test<int, int, char*> threevalues;
threevalues.Data = 1;
threevalues.Rest().Data = 2;
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.
template<class... _Types> class tuple;
template<> class tuple<> {};
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.
template<size_t _Index, class _Tuple> struct tuple_element;
template<class _This, class... _Rest>
struct tuple_element<0, tuple<_This, _Rest...>>
{
typedef _This& type;
typedef tuple<_This, _Rest...> _Ttype;
};
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 typedef
s, 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.
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) { }
Visual C++ 2013 compiles this fine, and the template type is inferred correctly.
Foo(12L); Foo(12.1); Foo('A'); Foo();
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, AltManager<int>>(25);
Not all arguments need to have defaults.
template <typename B, typename T = int> void Bar(B b = 0, T t = 0) { }
Bar(10); Bar(10L); Bar(10L, 20L); Bar();
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); Foo(12.1); Foo('A'); Foo();
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; }
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; }
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; Test1 t3 = t1; }
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) {
}
bool b = t3; }
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)
{
}
}
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) {
}
bar6(initializer_list<int>) {
}
};
bar6 b6 { 10, 10 };
Alright, that's it. As usual, feedback and criticism are very welcome. Thank you.
References
History
- July 20th, 2013 - Article published