Topic: proposed: non-deduced context scope resolution operator :0:
Author: cppljevans@cox-internet.com (Larry Evans)
Date: Sat, 8 Jan 2005 21:44:13 GMT Raw View
On 04/05/2004 12:04 PM, Larry Evans wrote:
> David Abrahams wrote:
[snip]
>> there's a simple logical impossibility here: the compiler can't deduce
>> the unknowable. If you hand me a type T there's no way I can tell you
>> which unique specialization of a template X has T as its 'type' member
>> because there may be many such specializations -- or none. There's no
>> way a simple syntax extension can help with that.
>
>
> Then there's some flaw in my resoning below. In particular, after the
> words:
>
> The proposed new token, :0:, would eliminate the need for these
> multiple specializations because with the specialization:
>
> Could you point out the flaw?
OK, I *finally* see the flaw. The responses to another recent thread
on c.l.c++.m with subject:
Question about non-deduced context
revealed what I belive you were talking about, i.e. given the following
template and specialization:
template<T>
struct X;
template<>
struct X<float>{ typedef int Y;};
template<>
struct X<int >{ typedef int Y;};
and given the following function template:
template <class T> void f( typename X<T>::Y );
and given the following call:
int i=2;
f(i);
the compiler couldn't know which one of the following to call:
f<int >(X<int >::Y);
f<float>(X<float>::Y);
and, of course the :0: operator couldn't solve the problem since
each Y is nested within the X<T>.
Sorry for not getting it sooner :(
Regards,
Larry
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 5 Apr 2004 05:06:59 +0000 (UTC) Raw View
cppljevans@cox-internet.com (Larry Evans) writes:
> David Abrahams wrote:
>> cppljevans@cox-internet.com (Larry Evans) writes:
> [snip]
>>>be used to solve the problem described by David Abrahams in:
>>>
>>>http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=uvflpetzg.fsf%40boost-consulting.com
>> I didn't really describe a problem, did I? Why do you think a
>> syntax
> No, sorry. I was looking at it from my viewpoint.
>> extension is needed here?
>>
> The workaround I'm using:
I don't understand your code, and no offense, but I probably don't
want to (**). A "workaround" is only applicable to a bug. AFAICT
there's a simple logical impossibility here: the compiler can't deduce
the unknowable. If you hand me a type T there's no way I can tell you
which unique specialization of a template X has T as its 'type' member
because there may be many such specializations -- or none. There's no
way a simple syntax extension can help with that.
** though if you care, reducing the code and the names used to the
minimum would help
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: cppljevans@cox-internet.com (Larry Evans)
Date: Mon, 5 Apr 2004 18:04:21 +0000 (UTC) Raw View
David Abrahams wrote:
David, thanks for you reply.
> cppljevans@cox-internet.com (Larry Evans) writes:
[snip]
> I don't understand your code, and no offense, but I probably don't
> want to (**). A "workaround" is only applicable to a bug. AFAICT
Sorry, my bad choice of words.
> there's a simple logical impossibility here: the compiler can't deduce
> the unknowable. If you hand me a type T there's no way I can tell you
> which unique specialization of a template X has T as its 'type' member
> because there may be many such specializations -- or none. There's no
> way a simple syntax extension can help with that.
Then there's some flaw in my resoning below. In particular, after the
words:
The proposed new token, :0:, would eliminate the need for these
multiple specializations because with the specialization:
Could you point out the flaw?
>
> ** though if you care, reducing the code and the names used to the
> minimum would help
Done, but some names are longer than 1 char to better illustrate their
purpose.
Code follows:
With the following helper class for eliminating non-deduced contexts:
template<typename T>
struct nester_of
//Purpose:
// nester_of<T>::type = void //general template, i.e. this one
// nester_of<N::T>::type = N //must be defined by specializations
{
typedef void type;
};
and given:
template<typename T>
struct A
{
template<typename T2>
struct B //nested smart ptr
{
T2* referent;
};
};
then nester_of requires, AFAICT, the following specialization for each
different s:
struct s{};
template<typename T2>
struct nester_of< A<s>::B<T2> > //#1
{
typedef A<s> type;
};
in order to get this to work:
template
< typename SP_applied //smart ptr applied to some referent type
>
class C;
template< typename Ref, typename SP_applied
, typename Nester >
class C_nester;
template< typename Ref, typename SP_applied >
class C_nester< Ref, SP_applied, void >
{
..
};
template
< typename Ref //SP referent type
, template<typename>class SP //smart pointer template
>
class C< SP<Ref> >
: public C_nester< Ref, SP<Ref>, typename nester_of<SP<Ref> >::type >
{
..
};
for the instantiation:
struct t2{};
C<A<s>::B<t2> > catbt2;
The reason #1 works is because there's no non-deduced context
because A<s> is an instantiation, i.e. it's like:
struct nester_of< As::B<T2> >
OTOH, as mentioned before, it requires a specialization for each
different s.
The proposed new token, :0:, would eliminate the need for these
multiple specializations because with the specialization:
template
< typename T2 //SP referent type
, template<typename>class B //smart pointer template
, typename A
, template<typename>class T
>
class C
< A<T>:0:B<T2>
>
{
..
};
there would be no ambiguity as with the :: in the examples:
A<int>::B<int> is base::B<int>
A<char*>::B<int> is base::B<int>
A<short>::B<int> is base::B<int>
A<T>::B<int> is base::B<int>
from:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=u8yik8ub8.fsf%40boost-consulting.com
because B<T2> is defined within the superclass of A<T>:
struct base {
template <class T2> struct B {};
};
template <class T>
struct A : base {};
and, as explained in:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=10709vpp8mcgtdd%40corp.supernews.com
A:0:B means B must be defined in the most derived class.
I hope I got it right this time :)
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: cppljevans@cox-internet.com (Larry Evans)
Date: Sun, 4 Apr 2004 16:08:28 +0000 (UTC) Raw View
Could the following new token:
:0:
meaning "*immediate* scope resolution", i.e.
T:0:S means S must be declared within T's member-specification as
defined in [gram.class] of the standard
be used to solve the problem described by David Abrahams in:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=uvflpetzg.fsf%40boost-consulting.com
? IOW, instead of:
A<T>::B<T2>
in 14.8.2.4p4, use:
A<T>:0:B<T2>
meaning there must be a template class:
template<typename T>class A;
defined something like:
template<typename T>class A
{
...
template<typename T2>class B;
...
};
Of course the reason for :0: is the 0 signifies "0 distance from the
most derived class" where distance means the number of "superclass.i"
operations to apply where "superclass.i" means the i-th superclass, for
i=0,...n-1 where n is the n-th superclass of a class.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 4 Apr 2004 17:26:04 +0000 (UTC) Raw View
cppljevans@cox-internet.com (Larry Evans) writes:
> Could the following new token:
>
> :0:
>
> meaning "*immediate* scope resolution", i.e.
>
> T:0:S means S must be declared within T's member-specification as
> defined in [gram.class] of the standard
>
> be used to solve the problem described by David Abrahams in:
>
> http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=uvflpetzg.fsf%40boost-consulting.com
I didn't really describe a problem, did I? Why do you think a syntax
extension is needed here?
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: cppljevans@cox-internet.com (Larry Evans)
Date: Sun, 4 Apr 2004 19:26:37 +0000 (UTC) Raw View
David Abrahams wrote:
> cppljevans@cox-internet.com (Larry Evans) writes:
[snip]
>>be used to solve the problem described by David Abrahams in:
>>
>>http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=uvflpetzg.fsf%40boost-consulting.com
>
>
> I didn't really describe a problem, did I? Why do you think a syntax
No, sorry. I was looking at it from my viewpoint.
> extension is needed here?
>
The workaround I'm using:
template<typename T>
struct nester_of
//Purpose:
// nester_of<T>::type = void //general template, i.e. this one
// nester_of<N::T>::type = N //must be defined by specializations
{
typedef void type;
};
requires, AFAICT, the following for each nester_template and nester_arg:
template<typename ReferentPtr>
struct nester_of
< nester_template<nester_arg>::owner<ReferentPtr>
>
{
typedef nester_template<nester_arg> type;
};
In order to get this to work:
template
< typename Referent
, typename StoragePolicy
, typename OwnershipPolicy
, typename Nester
>
class
cycle_basis_mgr_nester
;
template
< typename Referent
, typename StoragePolicy
, typename OwnershipPolicy
>
class
cycle_basis_mgr_nester
< Referent
, StoragePolicy
, OwnershipPolicy
, void
>
{
..
};
template
< typename Referent
, typename StoragePolicy
, template<typename>class OwnershipPolicy
>
class
cycle_basis_mgr< StoragePolicy, OwnershipPolicy<Referent*> >
: public cycle_basis_mgr_nester
< Referent
, StoragePolicy
, OwnershipPolicy<Referent*>
, typename nester_of<OwnershipPolicy<Referent*> >::type
>
{
..
};
I'm need a specialized cycle_basis_mgr_nester in case nester_of is:
curry_prox_visitor_refcycle_counted<prox_visitor_refcycle_abs>
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]