Feeds:
Posts
Comments

Archive for the ‘C++11’ Category

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

Read Full Post »

Continuing on with my blog series on C++ 11 support added in Visual C++ 2013, this one’s about 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.

Read Full Post »

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.

Read Full Post »

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.

Read Full Post »

I took a look at the std tuple header file (which I believe is authored/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).

Read Full Post »

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. There are correct ways to do this that I will write about in this blog. This example was merely for academic purposes.

Update – I’ve written a follow-up blog entry that shows the proper way to use variadic templates.

Read Full Post »

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.

Read Full Post »

The VC++ 2013 compiler supports variadic templates. They 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. I will be trying to blog more on the use of variadic templates in the near future.

Read Full Post »

In really simple terms, std::move returns an argument as an rvalue reference while std::forward returns either an lvalue reference or an rvalue reference based on how the argument was passed in to the current function. While this is fairly obvious once you get the hang of it, it can be quite tricky to grasp earlier on. The easiest way to see how they work differently is to try some code such as the following:

void Show(int&&)
{
	cout << "int&& called" << endl;
}

void Show(int&)
{
	cout << "int& called" << endl;
}

template<typename T> void Foo(T&& x)
{
	cout << "straight: ";
	Show(x);

	cout << "move: ";
	Show(move(x));
	
	cout << "forward: ";
	Show(forward<T>(x));
	
	cout << endl;
}

int _tmain(void)
{
	Foo(10);

	int x=10;
	Foo(x);
	return 0;
}

The output of the above code is:

straight: int& called
move: int&& called
forward: int&& called

straight: int& called
move: int&& called
forward: int& called

When Foo is called with an rvalue, T&& is deduced as int&&. But the variable itself is an lvalue within that function. So the straight call calls the Show(int&) overload – no surprises there. Both the move-call and the forward-call calls Show(int&&) as expected. In the 2nd case, Foo is called with an lvalue, and again the straight call will go to Show(int&) while the move-call will go to Show(int&&). Now here’s where forward comes in handy, it will go to Show(int&) because that’s what T has been deduced to in this instance of the function call (perfect forwarding). If you are wondering why, the collapsing rule for T&& collapses it to T& during template argument type deduction.

Read Full Post »

Follow

Get every new post delivered to your Inbox.