www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - can't use variadic template arg in dependent type

reply Larry Evans <cppljevans cos-internet.com> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

The code in 1st attachment compiles with output in 2nd attachment.
Is this a bug?  It seems that a sysmbol representing a variadic
temmplate arg can't be used to form a dependent type (IOW, Targs
can't be used to form A!(Targs) ).  This is in contrast to
how non-variadic symbols are treated :(
Jan 08 2007
next sibling parent reply Kyle Furlong <kylefurlong gmail.com> writes:
Larry Evans wrote:
 The code in 1st attachment compiles with output in 2nd attachment.
 Is this a bug?  It seems that a sysmbol representing a variadic
 temmplate arg can't be used to form a dependent type (IOW, Targs
 can't be used to form A!(Targs) ).  This is in contrast to
 how non-variadic symbols are treated :(
 
 
 
 
 
 ------------------------------------------------------------------------
 
 //Purpose:
 //  See if template function can take arg whose type
 //  is dependent on the template argument.
 
   class
 A
   ( Targs...
   )
 {
 }
 
   class
 B
   ( Targ
   )
 {
 }
 
 void funA(Targs...)(in A!(Targs) a)
 {
 }
 
 void funB(Targ)(in B!(Targs) a)
 {
 }
 
 void test()
 {
     A!(int,float) a_int_float;
     funA(a_int_float);
     B!(int) b_int;
     funB(b_int);
 }
 
 
 ------------------------------------------------------------------------
 
 cd /home/evansl/prog_dev/d-language/mpl/std/mpl/test/
 make variadic_dep_type-d.o
 /home/evansl/prog_dev/d-language/dmd/bin/dmd -c
-I/home/evansl/prog_dev/d-language/dmd/src/phobos variadic_dep_type.d
-ofvariadic_dep_type-d.o
 variadic_dep_type.d(30): template variadic_dep_type.funA(Targs...) does not
match any template declaration
 variadic_dep_type.d(30): template variadic_dep_type.funA(Targs...) cannot
deduce template function from argument types (A)
 make: *** [variadic_dep_type-d.o] Error 1
 
 Compilation exited abnormally with code 2 at Mon Jan  8 15:49:38

Does the: class AClass ( Args ) { } style that I've seen a few attachments use recently come from C++'s template nightmare? If so, please look at this: class AClass(Args) { } And let me know which is better! :D
Jan 08 2007
parent Larry Evans <cppljevans cos-internet.com> writes:
On 01/08/2007 05:02 PM, Kyle Furlong wrote:
[snip]
 
 Does the:
 
     class
 AClass
     ( Args
     )
 {
 }
 
 style that I've seen a few attachments use recently come from C++'s 
 template nightmare? If so, please look at this:
 
 class AClass(Args)
 {
 }
 
 And let me know which is better! :D

Maybe indirectly. It's mostly my own convention, and you're not the first to find it objectionable. I've used it because it emphasizes what's being defined (The class name). It won't grep as easily, but that's a problem with whatever's doing the grepping. There's other justifications, but, they probably wouldn't be of much interest.
Jan 08 2007
prev sibling parent reply Daniel Keep <daniel.keep+lists gmail.com> writes:
Larry Evans wrote:
 The code in 1st attachment compiles with output in 2nd attachment.
 Is this a bug?  It seems that a sysmbol representing a variadic
 temmplate arg can't be used to form a dependent type (IOW, Targs
 can't be used to form A!(Targs) ).  This is in contrast to
 how non-variadic symbols are treated :(

Ok, it took me a while, but I think I see what you're trying to do here. Have you tried something along these lines:
 class A(Targs...)
 {
     private static alias Targs _Targs;
 }

 void funA(Ttype)(in Ttype a)
 {
     alias Ttype._Targs Targs;
 }

If you really want to make sure that it's an A!(Targs), you could try this:
 static if( !is( A!(Targs) == Ttype ) )
     static assert(false, "I can see through your clever deception!");

Sometimes you need to just accept any old type, and then prune it down with static assert(false)s to the types you actually want (just have a look at my previous poorly named post on holy bovines for some type madness). Hope this helps, -- Daniel
Jan 09 2007
parent reply Larry Evans <cppljevans cos-internet.com> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

On 01/09/2007 03:15 AM, Daniel Keep wrote:
 Larry Evans wrote:

 Ok, it took me a while, but I think I see what you're trying to do here. 
  Have you tried something along these lines:
 
  > class A(Targs...)
  > {
  >     private static alias Targs _Targs;
  > }
  >
  > void funA(Ttype)(in Ttype a)
  > {
  >     alias Ttype._Targs Targs;
  > }
 
 If you really want to make sure that it's an A!(Targs), you could try this:
 
  > static if( !is( A!(Targs) == Ttype ) )
  >     static assert(false, "I can see through your clever deception!");

 Hope this helps,

Yes. It helps. However, the reason I want'ed to do this was to try and emulate the "trick" of using c++'s function template overload resolution rules to determine if a type was a member of an set of types, like boost's mpl::set. However, even with your suggestion, I'm still unable to do it. So far, what I've got is shown in the 1st attachemnt. The 2nd attachment shows the compiler error. This c++ "trick" was described on section 9.10 of the book described here: http://www.boost-consulting.com/metaprogramming-book.html and the cloest c++ counterpart to what I'm trying to do was posted in another message to this newsgroup: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=46428 The ultimate goal is to use a similar technique to store the grammar productions to emulate spirit.
Jan 09 2007
parent Larry Evans <cppljevans cos-internet.com> writes:
On 01/09/2007 11:12 AM, Larry Evans wrote:
[snip]
 This c++ "trick" was described on section 9.10 of the book
 described here:
 
 http://www.boost-consulting.com/metaprogramming-book.html
 
 and the cloest c++ counterpart to what I'm trying to do
 was posted in another message to this newsgroup:
 
 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmar
.D&article_id=46428 
 

Maybe I should explain this "trick". IIUC, for c++ function template: template<T0,T1,...,Tn> void f(T0 t0, T1 t1,...Tn tn); if the args are partially explicitly specified at the call, e.g.: f<A0,A1>(a0,a1,...an)l then the remaining template arguments, i.e. T2...Tn, are "wildcards", i.e. they can be anything that's consistent with the actual arguments, a2...an. In the case of the code in art_group=digitalmars.D&article_id=46428, the explicit argument was the type whose membership in the set was being queried. i.e. has_key_tester<int>(p_int_float) explicitly specifies the desired member, i.e. int, and the c++ function template overload resolution attempts to find a Tail... such that typeof(p_int_float) = set<int,Tail...> and, of course it does; hence, the result is mpl::boost_<true>. On the other hand, if no such Tail... is possible, then the more general has_key_tester is chosen and the result type is mpl::boost_<false>. I've looked at http://www.digitalmars.com/d/templates-revisited.html , and that seems closes to what I'm aiming at (since it does mention SFINAE); however, I still can't see how to do it. Does anyone else?
Jan 09 2007