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                       ]