.
[ Voor 118% gewijzigd door Eelis op 18-02-2015 19:36 ]
[ Voor 118% gewijzigd door Eelis op 18-02-2015 19:36 ]
1
| operator<< <V> (std::cout, e); |
Ik heb het idee dat Visual C++ 7.1 op de een of andere manier de namespaces opfukt, want ik zie niet in waarom 'ie bij de declaraties uit de iostream-header zou moeten komen, als operator<< uit de default namespace aangeroepen wordt.<knip>\Vc7\include\ios(24) : error C2039: 'int_type' : is not a member of 'V'
<knip>\test.cpp(12) : see declaration of 'V'
<knip>\include\ostream(36) : see reference to class template instantiation 'std::basic_ios<_Elem,_Traits>' being compiled
with
[
_Elem=char,
_Traits=V
]
<knip>\test.cpp(17) : see reference to class template instantiation 'std::basic_ostream<_Elem,_Traits>' being compiled
with
[
_Elem=char,
_Traits=V
]
[ Voor 11% gewijzigd door Soultaker op 23-02-2004 01:50 ]
een enum definitie is wel degelijk een zelfstandig type als ie niet anonymous is. Je kunt ook geen integral type aan een enum assignen zonder expliciet te casten. Je kunt een enum als template parameter specificeren (een int gebruiken bij instantiatie geeft dan ook een error), en het wordt meegenomen bij function overloadingSoultaker schreef op 23 februari 2004 @ 01:49:
De reden van de problemen lijkt me dat een enum-declaratie niet echt een zelfstandig type is, maar alleen wat constanten produceert. Dat is mijn speculatie; geen idee hoe dat in de standaarddocumentatie zit.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| #include <iostream> enum E { x, y }; std::ostream & operator << (std::ostream & o, E e) { return o << (e == x ? 'x' : 'y'); } int main () { E e = x; std::cout << e << std::endl; std::cout << y << std::endl; std::cout << (int)e << std::endl; return 0; } |
zoals je zou verwachten (VC++ 7.1)x
y
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #include <iostream> template <class T> struct S { enum E { x, y }; }; template <class T> void f (typename S<T>::E e) { std::cout << e << std::endl; } int main () { f (S<void>::x); } |
1
2
3
| test4.cpp(19) : error C2783: 'void f(S<T>::E)' : could not deduce template
argument for 'T'
test4.cpp(11) : see declaration of 'f' |
1
2
3
4
| "ComeauTest.c", line 19: error: no instance of function template "f" matches the
argument list
The argument types that you used are: (S<void>::E)
f (S<void>::x); |
-4- The nondeduced contexts are:
- The nested-name-specifier of a type that was specified using a qualified-id.
- A type that is a template-id in which one or more of the template-arguments is an expression that references a template-parameter.
- When a type name is specified in a way that includes a nondeduced context, all of the types that comprise that type name are also nondeduced. However, a compound type can include both deduced and nondeduced types. [Example: If a type is specified as A<T>::B<T2>, both T and T2 are nondeduced. Likewise, if a type is specified as A<I+J>::X<T>, I, J, and T are nondeduced. If a type is specified as void f(A<T>::B, A<T>), the T in A<T>::B is nondeduced but the T in A<T> is deduced. ]
[ Voor 59% gewijzigd door .oisyn op 23-02-2004 15:41 ]
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.
[ Voor 102% gewijzigd door Eelis op 18-02-2015 19:36 ]
[ Voor 28% gewijzigd door .oisyn op 23-02-2004 15: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.
[ Voor 149% gewijzigd door Eelis op 18-02-2015 19:36 ]
[ Voor 1% gewijzigd door .oisyn op 23-02-2004 18:22 . Reden: klote html-rechten :( ]
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.
[ Voor 111% gewijzigd door Eelis op 18-02-2015 19:36 ]
Nee:.oisyn schreef op 23 februari 2004 @ 18:21:
Da's idd een oplossing, alleen vervelend dat je dan van die vage errors krijgt bij het aanroepen van een operator << op een ostream en een type waarvoor ie eigenlijk niet gedefineerd is
Maar ik vind het eigenlijk ook raar. Als die E in S een typedef was geweest dan kan ik dat nog begrijpen: dan zal ie moeten backtracken over alle mogelijke specialisaties van S om te kijken of er toevallig in een van de S'en een typedef staat die klopt. Maar het gegeven type is gewoon een S<V>::E, dan moet ie daar toch ook direct de T=V uit af kunnen leiden
1
2
3
4
| template<>
class S<int> {
typedef S<float>::E E;
}; |
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
Dit is een open issue op de standaard; er is geen simpele oplossing voor. Waarschijnlijk moet je wachten tot C++0x. Nou is de vraag hoe de verschillende operator<<s afhangen van T, is een typedef geen mogelijkheid?Eelis schreef op 23 februari 2004 @ 00:45:
Stel ik heb de volgende class template:
C++:
1 2 3 template <typename T> struct S { enum E { a = T::x, b }; };
En stel vervolgens dat ik voor die E een operator<< wil definiëren die in plaats van de integer representaties netjes 'a' en 'b' naar een ostream streamed, en die ik aan wil kunnen roepen met:
C++:Hoe moet dat dan?
1 2 3 4 5 6 7 8 9 #include <iostream> struct V { static int const x = 9; }; int main () { S<V>::E e = S<V>::b; std::cout << e; return 0; }
Ik heb het volgende reeds geprobeerd:C++:Dit compileerde wel, maar de operator werd niet aangeroepen (de integer representatie werd gestreamed). Kennelijk lukt het de compiler (gcc 3.2.3) niet het E type te matchen.
1 2 3 4 template <typename T> std::ostream & operator<< (std::ostream & o, typename S<T>::E e) { return o << (e == S<T>::a ? 'a' : 'b'); }
Is er een andere manier om zo'n operator te definiëren die wel goed werkt? Wie helpt?
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
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.
ja maar dan is het een typedef, en dus in werkelijkheid gewoon een SMSalters schreef op 23 februari 2004 @ 21:14:
[...]
Nee:
code:
1 2 3 4template<> class S<int> { typedef S<float>::E E; };
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.
[ Voor 99% gewijzigd door Eelis op 18-02-2015 19:36 ]
Regels voor het overloaden van functies in namespace std, plus regels voor het gebruik van std:: functies door andere std::functies, plus misschien partiele functie specialisatie. Op het moment mag je in std:: alleen bestaande templates specialiseren, en functie templates kun je niet partieel specialiseren, dus een partiele specialisatie voor std::operator<< is onmogelijk.Eelis schreef op 24 februari 2004 @ 00:18:
[...]
Hmm, puur uit nieuwsgierigheid: welke nieuwe features of wijzigingen in C++0x gaan dit oplossen?
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
Yep - is dat geen probleem, als je een S<int>::E hebt gebruikt?.oisyn schreef op 23 februari 2004 @ 22:26:
[...]
ja maar dan is het een typedef, en dus in werkelijkheid gewoon een S<float>::E, waardoor het als T=float gededuceerd wordt.
1
2
3
4
5
6
7
8
9
| class S_base {
enum E { a, b };
};
template< typename T >
class S : public S_base {
};
// Specialisaties met separate S<T>::E
template <typename T>
std::ostream& operator<< ( std::ostream&, S<T>::E ); |
1
2
3
4
| template< int N >
class S {
enum E { SN = N };
}; |
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
nou ja mijn inziens niet, maar je hebt gelijk dat dat wel nogal verwarrend kan zijn natuurlijk. Maar met je laatste voorbeeld zie ik idd in dat het een probleem is.MSalters schreef op 24 februari 2004 @ 12:22:
[...]
Yep - is dat geen probleem, als je een S<int>::E hebt gebruikt?
[ Voor 55% gewijzigd door .oisyn op 24-02-2004 19:13 ]
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.
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