[C++] template error: member function already defined

Pagina: 1
Acties:
  • 129 views sinds 30-01-2008
  • Reageer

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ik heb een template structure, die een template member function heeft (operator =):

C++:
1
2
3
4
5
6
7
8
9
template<int i> struct S
{
    template<int j> S & operator = (const S<j> &)
    {
        return *this;
    }
};

S<0> s;


Onder VC7 krijg ik de error:
error C2535: 'S<i> &S<i>::operator =(const S<> &)' : member function already defined or declared
Terwijl ik toch niets fouts aan de code zie :?
(S<i> & returnen ipv S & werkt ook niet)

Ligt dit aan de compiler of doe ik gewoon iets fout?

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: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
hmmm als ik van de template argumenten een class maak ipv int dan werkt het wel

.edit: en het ligt ook alleen aan operator =
Als ik er een andere operator van maak dan werkt het prima

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: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
AHA!

ik denk dat het komt omdat de compiler een default assignment operator genereert. Als ik het returntype namelijk verander dan krijg ik een error dat ik 2 functies heb die alleen verschillen kwa return typen.

Als ik een extra operator = definieer die gewoon een S verwacht, dan verdwijnt de error:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<int i> struct S
{
    S & operator = (const S &)
    {
        return *this;
    }

    template<int j> S & operator = (const S<j> &)
    {
        return *this;
    }
};

S<0> s;



Ok, probleem is dus opgelost :) Maar wat ik me nu afvraag: is dit een van MSVC7's quirks of moet het gewoon zo volgens de C++ standaard. Ik denk eerlijk gezegd dat eerste, maar goed :Y)... ik heb net de Ansi C++ Draft, '96 working paper doorgelezen, en daar kan ik zo snel niet iets over vinden.

Oh trouwens met class ipv int deed ie het wel, dus het zal wel aan VC liggen :)

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

Handig, 'iemand' plaatst een post en lost 'm zelf binnen 3 kwartier op :)

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
als iedereen hier dat nou deed ;)

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.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:52
Ter informatie: gcc geeft geen kik bij het compileren van de allereerste code. Het lijkt dus toch op een MSVC wazigheidje.

Ik ben trouwens benieuwd wat deze klasse gaat doen?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Soultaker: ah ok weten we dat ook weer. Compiled het 2e stukje trouwens ook? (ivm de mogelijk dubbele functie of ambigiuteit als je de ene S<0> aan de andere S<0> assignt. Moet je wel even code toevoegen die die assignment uitvoert natuurlijk ;))

Wat de klasse gaat doen: deze struct is natuurlijk compleet gestript van alle dingen die totaal niets met deze topic te maken hadden, zodat zowel ik als de mensen die dit lezen zeker weten dat niets anders de boosdoener is :)

En als je wilt weten waarvoor ik het nodig heb: ik ben mijn 3d math lib aan het uitbreiden zodat je element swizzling kunt toepassen.

voorbeeldcode:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
Vector v1, v2;   // een Vector heeft een x, y, z en w element

v1 = 1, 2, 3, 4;  // v1 wordt nu (1, 2, 3, 4)

// deze 2 statements doen hetzelfde, v1 wordt v2
v2 = v1;
v2 = v1[x|y|z|w];

// met swizzling
v2 = v1[y|z|w|x];   // v2.x = v1.y,  v2.y = v1.z,  v1.z = v2.w,  v2.w = v1.x
v2[w|x|y|z] = v1;   // idem
v2 = v1[x|x|x|x];   // alle elementen van v2 wordt v1.x
v2[w|y|z|x] = 1, 2, 3, 4; // je raad het al :)

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: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
oh en hier trouwens de code: (dit is klad: ik moet nog wat doen aan de naamgeving enzo, plus het w-element zit er niet in)

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
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
struct Vector;


template<int i1> struct indexer1 { };
template<int i1, int i2> struct indexer2 { };
template<int i1, int i2, int i3> struct indexer3 { };

template<int i1, int i2> indexer2<i1, i2> operator | (indexer1<i1>, indexer1<i2>)
{
    return indexer2<i1, i2> ();
}

template<int i1, int i2, int i3> indexer3<i1, i2, i3> operator | (indexer2<i1, i2>, indexer1<i3>)
{
    return indexer3<i1, i2, i3> ();
}

indexer1<0> x;
indexer1<1> y;
indexer1<2> z;

indexer3<0, 1, 2> xyz;
indexer3<2, 1, 0> zyx;



template<int i1> struct setter1
{
    Vector & operator , (float f)
    {
        reinterpret_cast<Vector &> (*this)[i1] = f;
        return reinterpret_cast<Vector &> (*this);
    }
};

template<int i1, int i2> struct setter2
{
    setter1<i2> & operator , (float f)
    {
        reinterpret_cast<Vector &> (*this)[i1] = f;
        return reinterpret_cast<setter1<i2> &> (*this);
    }
};

template<int i1, int i2, int i3> struct setter3
{
    setter2<i2, i3> & operator = (float f)
    {
        (*this)()[i1] = f;
        return reinterpret_cast<setter2<i2, i3> &> (*this);
    }

    Vector & operator () ()
    {
        return reinterpret_cast<Vector &> (*this);
    }

    const Vector & operator () () const
    {
        return reinterpret_cast<const Vector &> (*this);
    }

    setter3 & operator = (const Vector & v)
    {
        (*this)()[i1] = v[0];
        (*this)()[i2] = v[1];
        (*this)()[i3] = v[2];
        return *this;
    }

    setter3 & operator = (const setter3 & s)
    {
        (*this)() = s ();
        return *this;
    }

    template<int i4, int i5, int i6> setter3 & operator = (const setter3<i4, i5, i6> & s)
    {
        (*this)()[i1] = s ()[i4];
        (*this)()[i2] = s ()[i5];
        (*this)()[i3] = s ()[i6];
        return *this;
    }
};



struct Vector
{
public:
    float x, y, z;

    const float & operator [] (int index) const
    {
        return *(&x + index);
    }

    float & operator [] (int index)
    {
        return *(&x + index);
    }

    template<int i1, int i2, int i3> setter3<i1, i2, i3> & operator [] (indexer3<i1, i2, i3>)
    {
        return reinterpret_cast<setter3<i1, i2, i3> &> (*this);
    }

    setter2<1, 2> & operator = (float f)
    {
        x = f;
        return reinterpret_cast<setter2<1, 2> &> (*this);
    }

    template<int i1, int i2, int i3> Vector & operator = (const setter3<i1, i2, i3> & s)
    {
        x = s ()[i1];
        y = s ()[i2];
        z = s ()[i3];
        return *this;
    }

    friend std::ostream & operator << (std::ostream & os, const Vector & v)
    {
        return os << '(' << v.x << ", " << v.y << ", " << v.z << ')';
    }
};


en die reinterpret_casts zijn ook niet zo netjes, maar dat scheelt weer een extra datamember en kan het dus beter geoptimalizeert worden

Oh de reden van deze topic was dus de struct setter3 :)

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
Vage bug, voornamelijk omdat die member helemaal niet geinstantieerd hoort te worden ->bodies zouden helemaal niet moeten uitmaken. Er is een expliciete regel die zegt (grofweg) dat de declaratie van een template (member) functie nooit de declaratie van een non-template (member) functie onmogelijk maakt. [13.3.3 Best Viable Function]

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