C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Sematischer unterschied zischen "type name(constr_arg);" und

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Marcel Müller
Guest





PostPosted: Wed Jun 15, 2005 8:17 pm    Post subject: Sematischer unterschied zischen "type name(constr_arg);" und Reply with quote



Hallo,

gibt es eingentlich jenseits der unterschiedlichen Syntax einen
semantischen Unterschied zwischen den beiden Schreibweisen

my_type my_var(expression);

und

my_type my_var = expression;

?

Meines Wissens sollte doch beides einen zum Typ von expression passenden
Konstruktor von my_type aufrufen.

Hintergrund:

Ich versuche gerade ein Programm der Art

template <typename T>
struct my_type_ref
{ my_type_ref() { }
};

template <typename T>
struct my_type
{ my_type() { }
my_type(T* p) { }
my_type(my_type<T>& r) { }
my_type(my_type_ref<T> r) { }
operator my_type_ref<T>() { }
};

int main()
{ my_type<int> x(new int()); // geht
my_type<int> y = new int(); // Fehler!
}

zu übersetzen. Aber in der markierten Zeile gibt es einen Fehler, den
ich mir nicht erklären kann (gcc 3.3.5).

testx.cpp: In function `int main()':
testx.cpp:17: error: no matching function for call to
`my_type<int>::my_type(my_type<int>)'
testx.cpp:11: error: candidates are:
my_type<T>::my_type(my_type_ref<T>) [with T = int]
testx.cpp:10: error: my_type<T>::my_type(my_type<T>&)
[with T = int]
testx.cpp:9: error: my_type<T>::my_type(T*) [with T = int]
testx.cpp:17: error: initializing temporary from result of
`my_type<T>::my_type(T*) [with T = int]'
testx.cpp:18:2: warning: no newline at end of file

Offenbar versucht der Compiler ein temporäres Objekt zu erzeugen (gut,
wenn er meint), dann aber den auto_ptr-artigen Umweg über den Typ
my_type_ref nicht hinzubekommen.
Den gewünschten Konstruktor my_type<int>::my_type(my_type<int>) kann es
ja nicht geben. Höchstens my_type<int>::my_type(my_type<int>&) oder
my_type<int>::my_type(const my_type<int>&) - der klassische
Copy-Konstruktor, der hier nicht erwünscht ist.

Oder hat der Compiler einfach eine Macke?


Marcel

--
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
Rolf Magnus
Guest





PostPosted: Thu Jun 16, 2005 9:13 am    Post subject: Re: Sematischer unterschied zischen "type name(constr_arg);" Reply with quote



Marcel Müller wrote:

Quote:
Hallo,

gibt es eingentlich jenseits der unterschiedlichen Syntax einen
semantischen Unterschied zwischen den beiden Schreibweisen

my_type my_var(expression);

und

my_type my_var = expression;

?

Meines Wissens sollte doch beides einen zum Typ von expression passenden
Konstruktor von my_type aufrufen.

Soweit schon. Aber die erste Variante erzeugt my_var direkt über den
"passenden" Konstruktor, während die zweite Variante mit diesem erst ein
temporäres Objekt vom Typ my_type konstruiert, dieses dann per
Kopierkonstruktor nach my_var kopiert, dann das temporäre Objekt wieder
löscht. Moderne Compiler können dieses temporäre Objekt wegoptimieren, so
daß im Prinzip das gleiche wie in der ersten Variante passiert. Die
C++-Norm erlaubt das auch explizit, aber da die Validität von Code nicht
vom Optimierungsverhalten des Compilers abhängen darf, muß in diesem Fall
trotzdem verlangt werden, daß der Kopierkonstruktor verfügbar ist.

Quote:
Hintergrund:

Ich versuche gerade ein Programm der Art

template <typename T
struct my_type_ref
{ my_type_ref() { }
};

template struct my_type
{ my_type() { }
my_type(T* p) { }
my_type(my_type my_type(my_type_ref<T> r) { }
operator my_type_ref<T>() { }
};

int main()
{ my_type<int> x(new int()); // geht
my_type<int> y = new int(); // Fehler!
}

zu übersetzen. Aber in der markierten Zeile gibt es einen Fehler, den
ich mir nicht erklären kann (gcc 3.3.5).

testx.cpp: In function `int main()':
testx.cpp:17: error: no matching function for call to
`my_type<int>::my_type(my_type<int>)'
testx.cpp:11: error: candidates are:
my_type<T>::my_type(my_type_ref<T>) [with T = int]
testx.cpp:10: error: my_type<T>::my_type(my_type<T>&)
[with T = int]
testx.cpp:9: error: my_type<T>::my_type(T*) [with T =
int]
testx.cpp:17: error: initializing temporary from result of
`my_type<T>::my_type(T*) [with T = int]'
testx.cpp:18:2: warning: no newline at end of file

Offenbar versucht der Compiler ein temporäres Objekt zu erzeugen (gut,
wenn er meint),

Richtig.

Quote:
dann aber den auto_ptr-artigen Umweg über den Typ my_type_ref nicht
hinzubekommen.
Den gewünschten Konstruktor my_type<int>::my_type(my_type<int>) kann es
ja nicht geben. Höchstens my_type<int>::my_type(my_type<int>&) oder
my_type<int>::my_type(const my_type<int>&) - der klassische
Copy-Konstruktor, der hier nicht erwünscht ist.

Nun, dein Konstruktor nimmt eine nicht-const-Referenz an. An diese kann man
aber keine temporären Objekte binden. Da die C++-Norm vorschreibt, daß ein
Kopierkonstruktor verfügbar ist, der mit einem temporären Objekt klarkommt,
funktioniert das so nicht.

Quote:
Oder hat der Compiler einfach eine Macke?

Nein, das Verhalten ist völlig konform.

--
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
Marcel Müller
Guest





PostPosted: Fri Jun 17, 2005 12:10 am    Post subject: Re: Sematischer unterschied zischen "type name(constr_arg);" Reply with quote



Rolf Magnus schrieb:
Quote:
my_type my_var(expression);

und

my_type my_var = expression;

Soweit schon. Aber die erste Variante erzeugt my_var direkt über den
"passenden" Konstruktor, während die zweite Variante mit diesem erst ein
temporäres Objekt vom Typ my_type konstruiert, dieses dann per
Kopierkonstruktor nach my_var kopiert, dann das temporäre Objekt wieder
löscht. Moderne Compiler können dieses temporäre Objekt wegoptimieren, so
daß im Prinzip das gleiche wie in der ersten Variante passiert. Die
C++-Norm erlaubt das auch explizit, aber da die Validität von Code nicht
vom Optimierungsverhalten des Compilers abhängen darf, muß in diesem Fall
trotzdem verlangt werden, daß der Kopierkonstruktor verfügbar ist.

Soweit klar, aber warum funktioniert in diesem Fall der Umweg über
my_type_ref nicht? Das Codeschnipsel

my_type<B> foo();

void bar(my_type<B> p);

int main()
{ my_type<B> x(foo());
bar(x);
}

funktioniert ja schließlich auch, obwohl zweimal der Copy-Konstruktor
benötigt wird. Statt dessen wird halt my_type::operator my_type_ref()
gefolgt von my_type::my_type(my_type_ref) aufgerufen.


Quote:
Nun, dein Konstruktor nimmt eine nicht-const-Referenz an. An diese kann man
aber keine temporären Objekte binden. Da die C++-Norm vorschreibt, daß ein
Kopierkonstruktor verfügbar ist, der mit einem temporären Objekt klarkommt,
funktioniert das so nicht.

Naja, die Norm sagt aber auch, daß sich ein Objekt mit definiertem
operator my_type_ref() überall da verwendet werden kann, wo auch ein
my_type_ref erlaubt ist. Und my_type ist doch über my_type_ref
konstruierbar. Das ist ja gerade der Trick, der auch bei auto_ptr
eingesetzt wird.


Quote:
Oder hat der Compiler einfach eine Macke?

Nein, das Verhalten ist völlig konform.

Irgendwie verstehe ich das noch nicht.


Marcel

--
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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.