Playing with C++0x


The new C++0x standard (sometimes called C++11) provides new interesting features, like variadic templates and tuples. So, I’m experimenting a bit in order to test the technical requirements to put in practise the proposal for a new BTL, and I hit a problem of the GCC (I guess).

Assume we have a set of Interfaces — I1 and I2 — that implement a method name(), which prints the name of the interface. And we have a set of template classes Actions — A1 and A2 — which take as template parameter an Interface — a class — and implement the method print() which prints the name of the action followed by the name of the interface. The code for this is the following (given that iostream is #included and cout exported in the main namespace):

template<typename Interface>
struct A1 {
	void print() {
		cout << "A1 - ";
		Interface i;
		i.print();
	}
};

template<typename Interface>
struct A2 {
	void print() {
		cout << "A2 - ";
		Interface i;
		i.print();
	}
};

struct I1 {
	void print() {
		cout << "I1\n";
	}
};
struct I2 {
	void print() {
		cout << "I2\n";
	}
};

Now we can do something like “A1<I2> action; action.print();” somewhere and have as result “A1 – I2”. And we can also write a function that takes an action and a set of interfaces (variadic template) and applies the same action on all these interfaces. The following code demonstrates this, by making use of a template tempalte parameter:

template<template<typename I> class Action>
void g1() {
	cout << "End of iteration\n";
}

template<template<typename I> class Action, class Interface1, class ... Interfaces>
void g1() {
	Action<Interface1> action;
	action.print();
	g1<Action, Interfaces...>();
}

template<template<typename I> class Action, class ... Interfaces>
void f1() {
	cout << "Begin iteration\n";
	g1<Action, Interfaces...>();
}
int main()
{
	f1<A1, I1, I2>();
}

The result is the desired:

Begin iteration
A1 - I1
A1 - I2
End of iteration

But now we want to do the opposite: given a single interface, apply many actions on it (at the end, what we want is to give many actions and many interfaces, but let’s proceed with small steps). In this case, we need to mix variadic templates and template template parameters, in the following way:

template<class Interface>
void g2() {
	cout << "End of iteration\n";
}

template<class Interface, template<class I> class Action1, template<class I> class ... Actions>
void g2() {
	Action1<Interface> action;
	action.print();
	g2<Interface, Actions...>();
}

template<class Interface, template<class I> class ... Actions>
void f2() {
	cout << "Begin iteration\n";
	g2<Interface, Actions...>();
}

This is just the same example transposed to single Interface – multiple Actions, and in theory it should work by just calling e.g. f2<I1, A1, A2>(); in the main function. But this will raise an error  when compiled with gcc:

variadic_template_template.cpp: In function ‘void f2() [with Interface = I1, Actions = A1, A2]’:
variadic_template_template.cpp:76:17:   instantiated from here
variadic_template_template.cpp:66:55: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
Preprocessed source stored into /tmp/ccaaQrEG.out file, please attach this to your bugreport.

The error message can change from platform to platform, but I tested it on Fedora, Gentoo, Debian and other, with many different versions of gcc and I always had this error. So I actually posted a bug report on the gcc bugzilla. There you can find some more technical details.

Can somebody test this with some other compiler? My icc refuses to work and I have no time right now to test the same with path64 or other compilers.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: