 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Andre Poenitz Guest
|
Posted: Sun Mar 19, 2006 4:06 pm Post subject: Template, namespaces |
|
|
Hallo alle.
Ich hab gerade wieder alten Code auf dem Tisch, der nicht mehr
kompiliert.
Im Wesentlichen soll sowas wie
class object;
class path;
namespace foo {
void to(object &, const object &);
void to(object &, const double &);
void to(object &, const int &);
void to(object &, const char &);
// ...
}
struct object
{
template <class T> void operator<<(const T & t) { foo::to(*this, t); }
};
struct path {};
namespace foo {
void to(object &, const path &) {}
}
int main()
{
object ob;
path p;
ob << p;
}
durch den Compiler gehen. Tut es mit g++ 4.0.2 aber nicht (wohl aber mit
aelteren Inkarnationen). Die Fehlermeldung:
1.C: In member function 'void object::operator<<(const T&) [with T = path]':
1.C:30: instantiated from here
1.C:16: error: no matching function for call to 'to(object&, const path&)'
1.C:6: note: candidates are: void foo::to(object&, const object&)
1.C:7: note: void foo::to(object&, const double&)
1.C:8: note: void foo::to(object&, const int&)
1.C:9: note: void foo::to(object&, const char&)
d.h. er behauptet, die Definition
void to(object &, const path &) {}
nicht zu finden.
Compilierbar wird es, wenn ich
(a) die Definition (zumindest als Deklaration) vor die Definition
der Klasse 'object' packe,
(b) den 'namespace foo' komplett weglasse.
Zwei Fragen:
Ist der Compiler im Recht?
Wenn ja, gibt es einfachere 'workarounds' um das Ganze nahe der
urspruenglichen Form compilierbar zu machen (also z.B. nur
Veraenderungen an der Definition des operator<<)?
Andre'
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Sun Mar 19, 2006 7:06 pm Post subject: Re: Template, namespaces |
|
|
Andre Poenitz <poenitz (AT) htwm (DOT) de> writes:
| Quote: | Im Wesentlichen soll sowas wie
class object;
class path;
namespace foo {
void to(object &, const object &);
void to(object &, const double &);
void to(object &, const int &);
void to(object &, const char &);
// ...
}
struct object
{
template <class T> void operator<<(const T & t) { foo::to(*this, t); }
};
struct path {};
namespace foo {
void to(object &, const path &) {}
}
int main()
{
object ob;
path p;
ob << p;
}
durch den Compiler gehen. Tut es mit g++ 4.0.2 aber nicht (wohl aber
mit aelteren Inkarnationen). Die Fehlermeldung:
1.C: In member function 'void object::operator<<(const T&) [with T = path]':
1.C:30: instantiated from here
1.C:16: error: no matching function for call to 'to(object&, const path&)'
1.C:6: note: candidates are: void foo::to(object&, const object&)
1.C:7: note: void foo::to(object&, const double&)
1.C:8: note: void foo::to(object&, const int&)
1.C:9: note: void foo::to(object&, const char&)
d.h. er behauptet, die Definition
void to(object &, const path &) {}
nicht zu finden.
Compilierbar wird es, wenn ich
(a) die Definition (zumindest als Deklaration) vor die Definition
der Klasse 'object' packe,
(b) den 'namespace foo' komplett weglasse.
Zwei Fragen:
Ist der Compiler im Recht?
|
Sieht so aus. Comeau sieht's gleich wie gcc 4. Ich bin auch überrascht.
| Quote: | Wenn ja, gibt es einfachere 'workarounds' um das Ganze nahe der
urspruenglichen Form compilierbar zu machen (also z.B. nur
Veraenderungen an der Definition des operator<<)?
|
Spezialisieren statt überladen. D.h.:
namespace foo {
template <typename T> void to(object &, T const &);
}
und dann die Versionen für object, double usw. als Spezialisierungen
davon, z.B.:
namespace foo {
template <> void to(object &, const path &) {}
}
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
M.Wagemeyer Guest
|
Posted: Sun Mar 19, 2006 8:06 pm Post subject: Re: Template, namespaces |
|
|
"Andre Poenitz" <poenitz (AT) htwm (DOT) de> schrieb im Newsbeitrag
news:d290f3-to.ln1 (AT) millo (DOT) mpi.htwm.de...
| Quote: |
Hallo alle.
Ich hab gerade wieder alten Code auf dem Tisch, der nicht mehr
kompiliert.
Im Wesentlichen soll sowas wie
class object;
class path;
namespace foo {
void to(object &, const object &);
void to(object &, const double &);
void to(object &, const int &);
void to(object &, const char &);
// ...
}
struct object
{
template <class T> void operator<<(const T & t) { foo::to(*this, t); }
};
struct path {};
namespace foo {
void to(object &, const path &) {}
}
int main()
{
object ob;
path p;
ob << p;
}
durch den Compiler gehen. Tut es mit g++ 4.0.2 aber nicht (wohl aber mit
aelteren Inkarnationen). Die Fehlermeldung:
1.C: In member function 'void object::operator<<(const T&) [with T =
path]':
1.C:30: instantiated from here
1.C:16: error: no matching function for call to 'to(object&, const
path&)'
1.C:6: note: candidates are: void foo::to(object&, const object&)
1.C:7: note: void foo::to(object&, const double&)
1.C:8: note: void foo::to(object&, const int&)
1.C:9: note: void foo::to(object&, const char&)
d.h. er behauptet, die Definition
void to(object &, const path &) {}
nicht zu finden.
Compilierbar wird es, wenn ich
(a) die Definition (zumindest als Deklaration) vor die Definition
der Klasse 'object' packe,
(b) den 'namespace foo' komplett weglasse.
Zwei Fragen:
Ist der Compiler im Recht?
Wenn ja, gibt es einfachere 'workarounds' um das Ganze nahe der
urspruenglichen Form compilierbar zu machen (also z.B. nur
Veraenderungen an der Definition des operator<<)?
Andre'
|
Hallo,
das hat so schon seine Richtigkeit.
An der Stelle an der deine Template Funktion steht ist die genau passende
(nicht Template-)Funktion einfach noch nicht bekannt.
Wenn du es ganz genau wissen möchtest schau dir mal den Artikel hier an:
http://www.cuj.com/documents/s=8024/cuj0107sutter/sutter.htm
Falls du da nicht schon registriert bist musst du dich erst anmelden bevor
du den kompletten Artikel lesen kannst.Es lohnt sich aber! Nicht nur wegen
dieses Artikels.
Gruß M.Wagemeyer
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Mon Mar 20, 2006 7:06 pm Post subject: Re: Template, namespaces |
|
|
Andre Poenitz wrote:
| Quote: | Ich hab gerade wieder alten Code auf dem Tisch, der nicht mehr
kompiliert.
Im Wesentlichen soll sowas wie
class object;
class path;
namespace foo {
void to(object &, const object &);
void to(object &, const double &);
void to(object &, const int &);
void to(object &, const char &);
// ...
|
Nur eine Frage, aber... Warum sind diese Funktionnen in einem
namspace, wenn object sich nicht in demselben namespace
befindet?
| Quote: | }
struct object
{
template <class T> void operator<<(const T & t) { foo::to(*this, t); }
};
struct path {};
namespace foo {
void to(object &, const path &) {}
}
int main()
{
object ob;
path p;
ob << p;
}
durch den Compiler gehen. Tut es mit g++ 4.0.2 aber nicht
(wohl aber mit aelteren Inkarnationen). Die Fehlermeldung:
1.C: In member function 'void object::operator<<(const T&) [with T = path]':
1.C:30: instantiated from here
1.C:16: error: no matching function for call to 'to(object&, const path&)'
1.C:6: note: candidates are: void foo::to(object&, const object&)
1.C:7: note: void foo::to(object&, const double&)
1.C:8: note: void foo::to(object&, const int&)
1.C:9: note: void foo::to(object&, const char&)
d.h. er behauptet, die Definition
void to(object &, const path &) {}
nicht zu finden.
|
Wenn ich die Norm richtig verstehe, hat er Recht. Soweit ich
verstanden habe (und es ist mir nicht ganz klar), ein
qualifizierten Funktionsname, wie foo::to, ist nur dependent,
wenn der Qualifizierer (hier, foo) dependent ist. Solange der
Name qualifiziert ist, wird er nicht durch den Typ eines
Parameters dependent werden.
Das heißt, dass der Namenslookup nur in der Umgebung der
Template-Definition stattfindet, nicht aber in der Umgebung der
Instantierung. Und in der Umgebung der Definition gibt es nur
vier Funktionned foo::to.
| Quote: | Compilierbar wird es, wenn ich
(a) die Definition (zumindest als Deklaration) vor die Definition
der Klasse 'object' packe,
(b) den 'namespace foo' komplett weglasse.
Zwei Fragen:
Ist der Compiler im Recht?
|
Ich denke wohl. Obwohl ich die Norm hier besonders schwierig zu
verstehen. Immerhin, laut §14.6.2/1:
In an expression of the form:
postfix-expression ( expression-list[opt] )
WHERE POSTFIX-EXPRESSION IS AN IDENTIFIER, the identifier
denotes a dependent name if and only if any of the
expressions in the expression-list is a type-dependent
expression.
In deinem Fall ist postfix-expression foo::to. Also, nicht ein
»identifier«. Und damit hast du verloren.
| Quote: | Wenn ja, gibt es einfachere 'workarounds' um das Ganze nahe
der urspruenglichen Form compilierbar zu machen (also z.B. nur
Veraenderungen an der Definition des operator<<)?
|
In Allgemein wurde ich sagen, dass eine freie Funktion stetts in
einem namespace gehört, wo einer seiner Parameter vereinbart
wird. Die richtige Lösung ist also, entweder object in foo zu
verlegen, oder die Funktionnen außer des namespaces.
Wenn solche Änderungen aber nicht möglich sind: Sicher bin ich
nicht, aber vielleicht funktionniert:
template <class T> void operator<<(const T & t) {
using namespace foo ;
to(*this, t);
}
In jedem Fall hier ist die postfix-expression ein »identifier«.
Damit wird er in »to(*this, t)« dependent. Wo ich aber unsicher
bin: Das Nachsuchen solcher dependent Namen in der Umgebung der
Instantierung aber verfolgt besondere Regeln, die ich nicht ganz
verstehe; siehe §14.6.4.2. (Ich führchte sogar, dass vielleicht
undefiniertes Verhalten damit entsteht. Leiter ist die Norm
nicht in einer Sprache geschrieben, die ich beherrsche.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Andre Poenitz Guest
|
Posted: Wed Mar 22, 2006 1:13 am Post subject: Re: Template, namespaces |
|
|
Thomas Maeder <jvxexluzrgmr (AT) mailinator (DOT) com> wrote:
| Quote: | Sieht so aus. Comeau sieht's gleich wie gcc 4. Ich bin auch überrascht.
|
Hmpf.
| Quote: | Wenn ja, gibt es einfachere 'workarounds' um das Ganze nahe der
urspruenglichen Form compilierbar zu machen (also z.B. nur
Veraenderungen an der Definition des operator<<)?
Spezialisieren statt überladen. D.h.:
namespace foo {
template <typename T> void to(object &, T const &);
}
|
Ein 'using namespace obj' im Koerper von operator<= tut's auch.
Find ich nicht huebsch, reiucht aber fuer'n Moment.
Andre'
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Andre Poenitz Guest
|
Posted: Wed Mar 22, 2006 1:22 am Post subject: Re: Template, namespaces |
|
|
kanze <kanze@gabi-soft.fr> wrote:
| Quote: | Andre Poenitz wrote:
Ich hab gerade wieder alten Code auf dem Tisch, der nicht mehr
kompiliert.
Im Wesentlichen soll sowas wie
class object;
class path;
namespace foo {
void to(object &, const object &);
void to(object &, const double &);
void to(object &, const int &);
void to(object &, const char &);
// ...
Nur eine Frage, aber... Warum sind diese Funktionnen in einem
namspace, wenn object sich nicht in demselben namespace
befindet?
|
'Historische Gruende'.
Aehm. Du meinst, wenn 'object' auch im namespace foo ware, waere das
Problem auch geloest?
| Quote: | }
struct object
{
template <class T> void operator<<(const T & t) { foo::to(*this, t); }
};
struct path {};
namespace foo {
void to(object &, const path &) {}
}
int main()
{
object ob;
path p;
ob << p;
}
durch den Compiler gehen. Tut es mit g++ 4.0.2 aber nicht
(wohl aber mit aelteren Inkarnationen). Die Fehlermeldung:
1.C: In member function 'void object::operator<<(const T&) [with T = path]':
1.C:30: instantiated from here
1.C:16: error: no matching function for call to 'to(object&, const path&)'
1.C:6: note: candidates are: void foo::to(object&, const object&)
1.C:7: note: void foo::to(object&, const double&)
1.C:8: note: void foo::to(object&, const int&)
1.C:9: note: void foo::to(object&, const char&)
d.h. er behauptet, die Definition
void to(object &, const path &) {}
nicht zu finden.
Wenn ich die Norm richtig verstehe, hat er Recht. Soweit ich
verstanden habe (und es ist mir nicht ganz klar), ein
qualifizierten Funktionsname, wie foo::to, ist nur dependent,
wenn der Qualifizierer (hier, foo) dependent ist. Solange der
Name qualifiziert ist, wird er nicht durch den Typ eines
Parameters dependent werden.
Das heißt, dass der Namenslookup nur in der Umgebung der
Template-Definition stattfindet, nicht aber in der Umgebung der
Instantierung.
|
Naja, so fuehlt sich's jedenfalls an.
| Quote: | Und in der Umgebung der Definition gibt es nur
vier Funktionned foo::to.
Compilierbar wird es, wenn ich
(a) die Definition (zumindest als Deklaration) vor die Definition
der Klasse 'object' packe,
(b) den 'namespace foo' komplett weglasse.
Zwei Fragen:
Ist der Compiler im Recht?
Ich denke wohl. Obwohl ich die Norm hier besonders schwierig zu
verstehen. Immerhin, laut §14.6.2/1:
In an expression of the form:
postfix-expression ( expression-list[opt] )
WHERE POSTFIX-EXPRESSION IS AN IDENTIFIER, the identifier
denotes a dependent name if and only if any of the
expressions in the expression-list is a type-dependent
expression.
In deinem Fall ist postfix-expression foo::to. Also, nicht ein
»identifier«. Und damit hast du verloren.
Wenn ja, gibt es einfachere 'workarounds' um das Ganze nahe
der urspruenglichen Form compilierbar zu machen (also z.B. nur
Veraenderungen an der Definition des operator<<)?
In Allgemein wurde ich sagen, dass eine freie Funktion stetts in
einem namespace gehört, wo einer seiner Parameter vereinbart
wird. Die richtige Lösung ist also, entweder object in foo zu
verlegen, oder die Funktionnen außer des namespaces.
Wenn solche Änderungen aber nicht möglich sind: Sicher bin ich
nicht, aber vielleicht funktionniert:
template <class T> void operator<<(const T & t) {
using namespace foo ;
to(*this, t);
}
|
Ja, geht. Danke.
| Quote: | In jedem Fall hier ist die postfix-expression ein »identifier«.
Damit wird er in »to(*this, t)« dependent. Wo ich aber unsicher
bin: Das Nachsuchen solcher dependent Namen in der Umgebung der
Instantierung aber verfolgt besondere Regeln, die ich nicht ganz
verstehe; siehe §14.6.4.2. (Ich führchte sogar, dass vielleicht
undefiniertes Verhalten damit entsteht. Leiter ist die Norm
nicht in einer Sprache geschrieben, die ich beherrsche.)
|
Ich fuerchte, die Menge der lebenden Personen, die die Sprache
des Standards vollstaendig beherrschen, ist sowieso leer.
Ok, ich schau mal, ob ich 'object' billig in den Namensraum 'foo'
verschieben kjann, dann erscheint mir das die 'langfristig stabilere'
Loesung zu sein als das 'using', bei dem ich irgendwie leichtes
Bauchdruecken habe.
Danke auf jeden Fall fuer Eure Hilfe.
Andre'
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|