Topic: Concepts and conversions
Author: s.hesp@oisyn.nl ("Sylvester Hesp")
Date: Fri, 4 May 2007 16:11:38 GMT Raw View
"Douglas Gregor" <doug.gregor@gmail.com> wrote in message
news:1177513356.654845.101050@r3g2000prh.googlegroups.com...
> On Apr 20, 7:07 am, tasjae...@gmail.com wrote:
>> I have a question about how function parameter conversions will work
>> when the function signature is declared in a concept.
> [snip
>> My question is, if a constrained function template uses Pootle as
>> follows:
>>
>> template <Pootle P>
>> void g(P&& p) { f(p, X()); }
>>
>> will this work with S as the template parameter? In particular, is a
>> double conversion performed (from X->Y->Z)?
>
> Yes, there is a double-conversion here. The first conversion is
> performed inside the g(), to turn the X into a Y when calling
> Pootle<P>::f. The second conversion occurs inside the concept map
> Pootle<S>.
Is such a double conversion always performed, even if the 1st and 3rd types
(X and Z in the example) are equal? E.g.
struct X { X(Y); };
struct Y { Y(X); };
concept MyConcept<class T> { void f(T, Y); }
struct MyStruct { };
void f(MyStruct, X);
concept_map MyConcept<MyStruct> { };
template<MyConcept T> void foo(T t)
{
f(t, X()); // #1
MyConcept<T>::f(t, X()); // #2
};
Would #1 convert X to Y, and then back to X? Or would it first try to
convert X directly to X, skipping the conversion that was introduced by the
signature in the concept, and only if that fails do a double-conversion? Or
would it simply find f(MyStruct,X) in the global scope and use that instead,
bypassing the concept altogether? But in the latter case, what about #2?
N2081 is a bit unclear about this.
- Sylvester Hesp
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: tasjaevan@gmail.com
Date: Fri, 20 Apr 2007 05:07:31 CST Raw View
I have a question about how function parameter conversions will work
when the function signature is declared in a concept.
Say you have the following types (specifically defined for the
conversions between them):
struct X {};
struct Y { Y(); Y(X); };
struct Z { Z(); Z(Y); };
and a concept which deals with the 'middle' type:
concept Pootle<class T> { void f(T, Y); }
If I understand correctly, the following type can model this concept:
struct S {};
void f(const S&, Z);
concept_map Pootle<S> {}
since Z is convertible to Y.
My question is, if a constrained function template uses Pootle as
follows:
template <Pootle P>
void g(P&& p) { f(p, X()); }
will this work with S as the template parameter? In particular, is a
double conversion performed (from X->Y->Z)?
Thanks
James
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-1?q?Pedro_Lamar=E3o?= <pedro.lamarao@gmail.com>
Date: Fri, 20 Apr 2007 11:34:17 CST Raw View
On 20 abr, 08:07, tasjae...@gmail.com wrote:
> My question is, if a constrained function template uses Pootle as
> follows:
>
> template <Pootle P>
> void g(P&& p) { f(p, X()); }
>
> will this work with S as the template parameter? In particular, is a
> double conversion performed (from X->Y->Z)?
For this piece of code:
// begin code
struct X { };
struct Y { Y(); Y(X); };
struct Z { Z(); Z(Y); };
struct S { };
void
f (S const&, Z);
template <typename T>
void
g (T const& t) { f(t, X()); }
void
h () { g(S()); }
//end code
Visual Studio 2005 gives me the error:
------ Build started: Project: tmp2, Configuration: Debug Win32 ------
Compiling...
test.cpp
c:\documents and settings\psilva\meus documentos\visual studio
2005\projects\remoting\tmp2\test.cpp(12) : error C2664: 'f' : cannot
convert parameter 2 from 'X' to 'Z'
No user-defined-conversion operator available that can perform
this conversion, or the operator cannot be called
c:\documents and settings\psilva\meus documentos\visual studio
2005\projects\remoting\tmp2\test.cpp(15) : see reference to function
template instantiation 'void g<S>(const T &)' being compiled
with
[
T=S
]
Build log was saved at "file://c:\Documents and Settings\psilva\Meus
documentos\Visual Studio 2005\Projects\Remoting\tmp2\Debug
\BuildLog.htm"
tmp2 - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped
==========
I believe the reason is just that only one user-defined conversion is
allowed.
This rule should not be affected by the use of concept maps.
--
Pedro Lamar o
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: tasjaevan@gmail.com
Date: Mon, 23 Apr 2007 22:56:38 CST Raw View
On Apr 20, 6:34 pm, Pedro Lamar o <pedro.lama...@gmail.com> wrote:
> On 20 abr, 08:07, tasjae...@gmail.com wrote:
>
> > My question is, if a constrained function template uses Pootle as
> > follows:
>
> > template <Pootle P>
> > void g(P&& p) { f(p, X()); }
>
> > will this work with S as the template parameter? In particular, is a
> > double conversion performed (from X->Y->Z)?
>
>
> Visual Studio 2005 gives me the error:
>
> ------ Build started: Project: tmp2, Configuration: Debug Win32 ------
> Compiling...
> test.cpp
> c:\documents and settings\psilva\meus documentos\visual studio
> 2005\projects\remoting\tmp2\test.cpp(12) : error C2664: 'f' : cannot
> convert parameter 2 from 'X' to 'Z'
> No user-defined-conversion operator available that can perform
> this conversion, or the operator cannot be called
>
> <snip>
> I believe the reason is just that only one user-defined conversion is
> allowed.
>
Yes, only a single conversion is allowed in the current language.
>
> This rule should not be affected by the use of concept maps.
>
ConceptGCC also rejects my example code due to the double conversion,
so that would seem to agree with you.
But isn't there something broken about it? My S models Pootle. My g is
using Pootle correctly within a constrained template. Result: syntax
error.
I think a double conversion is correct in this situation. If you look
at N2081 (paragraph 3.3.3), it says that, since
concept_map Pootle<S> {}
does not provide a definition for f, a forwarding function is
generated. Something like:
concept_map Pootle<S> { void f(const S& s, Y y) { f(s, y); }}
So there are effectively two functions, each one performing one
conversion.
James
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-1?q?Pedro_Lamar=E3o?= <pedro.lamarao@gmail.com>
Date: Tue, 24 Apr 2007 12:15:28 CST Raw View
On 24 abr, 01:56, tasjae...@gmail.com wrote:
> I think a double conversion is correct in this situation. If you look
> at N2081 (paragraph 3.3.3), it says that, since
>
> concept_map Pootle<S> {}
>
> does not provide a definition for f, a forwarding function is
> generated. Something like:
>
> concept_map Pootle<S> { void f(const S& s, Y y) { f(s, y); }}
>
> So there are effectively two functions, each one performing one
> conversion.
I see your point.
The function f in scope satisfies the concept but doesn't have the
exact signature required, and the language in 3.3.3 tells us this
exact f should be implicitly generated.
But this seems strange.
I would expect that the concept Pootle is fully satisfied by the type
S -- because there is a proper f in scope.
The language on section 3 seems to require that every concept_map
provide this function f for S either explicitly or through an implicit
(forwarding) definition, no matter what.
So what should happen in this case?
struct P { };
void f (P, Z) { }
concept_map Pottle<P> { };
Should this fail because the concept_map will implicitly generate a
new, ambiguous, f?
Am I missing something?
I admit I haven't studied N2081 in full detail.
--
Pedro Lamar o
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Douglas Gregor <doug.gregor@gmail.com>
Date: Wed, 25 Apr 2007 11:47:19 CST Raw View
On Apr 20, 7:07 am, tasjae...@gmail.com wrote:
> I have a question about how function parameter conversions will work
> when the function signature is declared in a concept.
[snip
> My question is, if a constrained function template uses Pootle as
> follows:
>
> template <Pootle P>
> void g(P&& p) { f(p, X()); }
>
> will this work with S as the template parameter? In particular, is a
> double conversion performed (from X->Y->Z)?
Yes, there is a double-conversion here. The first conversion is
performed inside the g(), to turn the X into a Y when calling
Pootle<P>::f. The second conversion occurs inside the concept map
Pootle<S>.
ConceptGCC does not properly compile this code, but the code is
correct.
- Doug
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]