Bonjour,

Dans le code situ� � la fin de ce message, j'ai une classe 'exec' template avec plusieurs param�tres. Le dernier param�tre est l'adresse d'une m�thode, dont le type est d�termin� par les autres param�tres. La fonction 'maker' de ce code doit, �tant donn� une m�thode d'une classe, retourner une instance de 'exec' o� les types auront �t� d�termin�s automatiquement.

Lorsque je compile cet exemple, avec g++ 4.3 ou 4.4, j'ai l'erreur suivante :
test_f_temp.cpp: In member function �void exec<C, R, A1, A2, method_name>::caller::run(base_object&) const [with C = T1, R = int, A1 = int, A2 = double, R (C::* method_name)(A1, A2) = method_name]�:
test_f_temp.cpp:30: internal compiler error: in expand_expr_real_1, at expr.c:7314
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.4/README.Bugs> for instructions.
Je ne vois pas ce qui le perturbe dans le code, alors je cherche une alternative que mon compilateur appr�cierait plus. Remarquez, de plus, que le probl�me ne se pose que pour l'appel � 'maker'. La partie concernant 'c0' dans le main() passe tr�s bien.

Pourriez-vous me dire si vous voyez un probl�me dans le code*? si �a compile bien avec votre compilateur et si vous voyez une alternative*?

Cordialement,

Julien

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
70
71
72
73
74
75
#include <iostream>
 
class base_object
{
public:
  virtual ~base_object() { }
}; // class base_object
 
// classe mère pour la classe exec::caller ci-dessous
class base_caller
{
public:
  virtual void run(base_object& i) const = 0;
}; // class base_caller
 
// Cette classe définit une dérivée de base_caller pour appeler une méthode de
// la classe C, de type de retour R et dont les paramètres sont de type A1, ...,
// An. Une instance de ce caller est crée.
template< typename C, typename R, typename A1, typename A2,
          R (C::*method_name)(A1, A2) >
class exec
{
public:
  typedef R (C::*method_type)(A1, A2);
 
public:
  class caller:
    public base_caller
  {
  public:
    virtual void run(base_object& i) const
    {
      C& inst( dynamic_cast<C&>(i) );
      const method_type m(method_name);
      (inst.*m)(1, 0);
    }
  }; // class caller
 
  static caller instance;
}; // class exec
 
template< typename C, typename R, typename A1, typename A2,
          R (C::*method_name)(A1, A2) >
typename exec<C, R, A1, A2, method_name>::caller
exec<C, R, A1, A2, method_name>::instance;
 
// méthode pour trouver l'instance de exec<>::instance qui convient en fonction
// de la fonction à appeler.
template<typename C, typename R, typename A1, typename A2>
base_caller* maker( R (C::*method_name)(A1, A2) )
{
  return &exec<C, R, A1, A2, method_name>::instance;
}
 
// petit exemple
class T1:
  public base_object
{
public:
  int test( int a, double b )
  { std::cout << "T1" << std::endl; return 0; }
};
 
int main()
{
  T1 t1;
 
  base_caller* c0 = &exec<T1, int, int, double, &T1::test>::instance;
  c0->run(t1);
 
  base_caller* c1 = maker( &T1::test );
  c1->run(t1);
 
  return 0;
}