Bonjour tous,

Dans mon projet, la plupart de mes « classes » sont des typedefs de templates variadiques. Ça fait du code joli et concis, jusque là tout va bien.

Sauf que souvent ces typedefs font références les uns aux autres. Pour résoudre les problèmes de dépendances cycliques engendrés, je dois écrire des pimpl. Et l'interface est plutôt lourde à reproduire…
Par exemple, alors qu'un typedef donnerait ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
typedef
	alternative_node
	<
		simple_declaration,
		asm_definition,
		namespace_alias_definition,
		using_declaration,
		using_directive
	>
	block_declaration
;
… je dois remplacer le code ci-dessus par celui-ci, pour mettre en place le pimpl (ne vous souciez pas du sens de ce code, ce n'est pas le sujet) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 
/*certains des types présents dans ce typedef sont incomplets*/
typedef
	alternative_node
	<
		simple_declaration,
		asm_definition,
		namespace_alias_definition,
		using_declaration,
		using_directive
	>
	block_declaration_t
;
 
typedef
	alternative_node
	<
		asm_definition,
		namespace_alias_definition,
		using_declaration,
		using_directive
	>
	block_declaration_tail_t
;
 
class block_declaration: public composite_node
{
	public:
		typedef block_declaration_t type;
		typedef simple_declaration head_node_t;
		typedef block_declaration_tail_t tail_alternative_node_t;
 
		block_declaration(simple_declaration&& o);
 
		block_declaration(asm_definition&& o);
 
		block_declaration(namespace_alias_definition&& o);
 
		block_declaration(using_declaration&& o);
 
		block_declaration(using_directive&& o);
 
		block_declaration(const block_declaration& o);
 
		block_declaration(block_declaration&& o);
 
		~block_declaration();
 
		const block_declaration&
		operator=(const block_declaration& o);
 
		void
		get(boost::optional<const simple_declaration&>& node) const;
 
		void
		get(boost::optional<const asm_definition&>& node) const;
 
		void
		get(boost::optional<const namespace_alias_definition&>& node) const;
 
		void
		get(boost::optional<const using_declaration&>& node) const;
 
		void
		get(boost::optional<const using_directive&>& node) const;
 
	private:
		std::unique_ptr<type> impl_;
};
Comme vous le voyez, c'est un tantinet verbeux. Et encore, je n'ai pas mis les définitions des fonctions membres.

Voici donc ma question : Existe-t-il une technique de métaprogrammation (certainement à base de macros) qui me permettrait de factoriser le code ci-dessus par quelque chose comme celui-ci ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
ALTERNATIVE_NODE_PIMPL
(
	block_declaration,
	simple_declaration,
	asm_definition,
	namespace_alias_definition,
	using_declaration,
	using_directive
)
Même si le nombre d'arguments doit être spécifié, je prends aussi !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
ALTERNATIVE_NODE_PIMPL5
(
	block_declaration,
	simple_declaration,
	asm_definition,
	namespace_alias_definition,
	using_declaration,
	using_directive
)