[C++] template name resolution voor member templates

Pagina: 1
Acties:

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ik snap iets niet

C++:
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
struct B
{
    typedef int int_type;
    template <class T> struct InnerB { };
};

struct G
{
    typedef B other;
};

template <class T> void func (const T &)
{
    G::other b1;  // ok
    typename T::other b2;  // ok

    G::other::InnerB<int> ib;  // ok
    typedef typename T::other other;  // ok
    typename other::int_type i;  // ok
    typename other::InnerB<int> b;  // <-- fout!
}

int main ()
{
    B::InnerB<int> b;
    G::other::InnerB<int> b2;

    G g;
    func (g);

    return 0;
}


Comeau komt hier met de error:
code:
1
2
3
4
error: template parameter "T::other::InnerB" may not have a
          template argument list
    typename other::InnerB<int> b;
                    ^


typename weghalen helpt niet, zoals ook zou horen. Maar hoe kun je de compiler duidelijk maken dat dat een template type is?

Ook loopt ie nogal de soep in als je die InnerB als template class mee wilt geven als template argument:

C++:
1
2
3
4
5
6
7
8
template <template <class> class T> struct A { };

template <class T> void func (const T &)
{
    typedef typename T::other other;
    A<G::other::InnerB> a1;  // ok
    A<other::InnerB> a2;  // fout!
}


Nu zegt ie dat nontype other::InnerB geen class template is. Als ik er typename voor zet begint ie te klagen over dat ie een identifier verwacht op de plaats waar typename staat.

Ik kan in de standaard verder ook weinig vinden.

[ Voor 19% gewijzigd door .oisyn op 10-05-2003 01:40 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Argh natuurlijk |:(
14.2.4: When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (temp.dep), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template
oplossingen:
C++:
1
2
typename other::template InnerB<int> b;
A<other::template InnerB> a2;

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

En wederom stelt oisyn een vraag die hijzelf al beantwoord had voordat iemand anders de kans had om 'm te lezen :)

* curry684 heeft ook die neiging overigens :P

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ik vind overigens wel dat dit behoorlijke rommel geeft in je code... ik snap dat het wel min of meer nodig omdat het anders ambigue is, maar het moet toch anders kunnen. Bovendien slikt MSVC 7 het ook zonder typename en template, dus het kan wel (hoewel de parse-volgorde in MSVC niet helemaal juist is)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
.oisyn, het probleem is niet dat het in deze situatie overbodig is, maar dat de grens tussen nodig en niet nodig te complex is. Daarom is er een "simpele" grens getrokken (template/typename alleen als het door een specialisatie iets anders zou kunnen zijn), die voor alle compiler vendors eenvoudig te implementaren is.

Als je er gelukkig van wordt, in de toekomst mag je in elk geval typename op non-dependent names gebruiken, dat is dan uitsluitend documentatie. template in zo'n
situatie is ben ik bang over het hoofd gezien, zal even checken en zoniet dan gooi ik
het in de groep. Just in case: Welke naam wil je op het Defect Report? :)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 106% gewijzigd door Eelis op 18-02-2015 19:41 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
MSalters schreef op 12 mei 2003 @ 01:22:
Welke naam wil je op het Defect Report? :)
Sylvester Hesp *D

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Eelis schreef op 12 mei 2003 @ 05:44:
[...]

Bedoel je dat je dan ook 'typename' mag gaan gebruiken waar het niet nodig is? Als dat het geval is vind ik de toegevoegde consistentie daarvan bepaald niet opwegen tegen de toegevoegde verbositeit, en wat mij betreft wordt het er daar alleen maar lelijker van.. Maar ach, syntax is nooit de sterkste kant van C++ geweest ;).
Nou nou, zo erg is het ook weer niet:
code:
1
2
3
4
5
6
7
8
9
10
11
template < typename T >
class foo() {
  typename A<T>::type obj1; // Simpel: Hier moet typename
  template < typename U >
  struct B {
    typedef T type_t;
    typedef U type_u;
  };
  typename B<int>::type_t obj2; // Hier mag het. Moet het?
  typename B<int>::type_u obj3;// Hier mag het. Moet het?
};

offtopic:
he modjes, fix die C++0x parser es :Y)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
MSalters schreef op 12 May 2003 @ 20:31:
offtopic:
he modjes, fix die C++0x parser es :Y)
Daarvoor moet je bij een zekere S. Hesp wezen :Y)

  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 99% gewijzigd door Eelis op 18-02-2015 19:41 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
offtopic:
Neu, had eerst void foo() maar toch maar class van gemaakt.


Het probleem zit 'm niet in de simpele gevallen, nee. Aan de andere kant, is X een object of een type?
code:
1
2
3
4
template < typename T, typename U >
void foo( U u ) {
  A<T>::X( u ); 
};

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 98% gewijzigd door Eelis op 18-02-2015 19:41 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Niet op moment van parsen, omdat er na die functie misschien wel een A<T> is gespecializeerd waar X misschien wel heel wat anders is dan de algemene versie van A<T>

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <class T>
struct A
{
    typedef int X;
};

template < typename T, typename U >
void foo( U u ) {
  A<T>::X( u ); 
};

template <>
struct A<char>
{
    static void X (int) { }
};


int main ()
{
    foo<int> (3);    // gebruikt algemene A, A<int>::X is een type
    foo<char> (3);   // gebruikt gespecializeerde A<char>, A<char>::X is een functie
}


De enige oplossing hiervoor is een superset van C++ parsen, en dan bij de semantische analyse kijken wat er nou _echt_ bedoeld wordt.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 99% gewijzigd door Eelis op 18-02-2015 19:41 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Het probleem is dat als je niet weet wat een token representeert, variabele of type of template, dat je dan het vervolg niet meer tot een tree kunt parsen. Stel, X is wat ik tot nu toe heb, variabele of type of template. Wat is X< A > B dan? Een declaratie of een expressie? Is dat een template argument lijst, of een groter dan A kleiner dan B?

Je oplossing om de resolutie later te doen is leuk, ware het niet dat dat icm export je aan het einde van het compilen niet de hele instantiatie context hebt gezien.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1