April 15, 2008 Re: Template Question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter wrote:
> Mike Parker wrote:
>> Mike Parker wrote:
>>> Bill Baxter wrote:
>>>> Mike Parker wrote:
>>>>> Bill Baxter wrote:
>>>>>> Mike Parker wrote:
>>
>>>
>>> This is exactly what I was looking for. I don't understand it, but it works.
>>
>> Actually, it doesn't work.
>
> Ok, so in that case...
> I think you can put an alias for the type inside an interface, and use that to work around:
>
> interface Foo(T)
> {
> alias T TheType;
> void init(T);
> }
>
> ...
> static if ( is(U : Foo!(U.TheType)) ) {
> ...
> }
>
> That seems to work.
>
Yes, this works. But, the static if evaluation never completes if U does not have TheType. It craps out with errors as soon as U.TheType is encountered rather than printing out the more friendly static assert.
|
April 15, 2008 Re: Template Question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | Mike Parker wrote:
> Bill Baxter wrote:
>> Mike Parker wrote:
>>> Mike Parker wrote:
>>>> Bill Baxter wrote:
>>>>> Mike Parker wrote:
>>>>>> Bill Baxter wrote:
>>>>>>> Mike Parker wrote:
>>>
>>>>
>>>> This is exactly what I was looking for. I don't understand it, but it works.
>>>
>>> Actually, it doesn't work.
>>
>> Ok, so in that case...
>> I think you can put an alias for the type inside an interface, and use that to work around:
>>
>> interface Foo(T)
>> {
>> alias T TheType;
>> void init(T);
>> }
>>
>> ...
>> static if ( is(U : Foo!(U.TheType)) ) {
>> ...
>> }
>>
>> That seems to work.
>>
>
> Yes, this works. But, the static if evaluation never completes if U does not have TheType. It craps out with errors as soon as U.TheType is encountered rather than printing out the more friendly static assert.
I don't understand. Can't you just make it
static assert(is(U : Foo!(U.TheType))),
"Use a Foo!() don't be a Foo! -- Mr. T");
--bb
|
April 15, 2008 Re: Template Question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter wrote:
> Mike Parker wrote:
>> Bill Baxter wrote:
>>> Mike Parker wrote:
>>>> Mike Parker wrote:
>>>>> Bill Baxter wrote:
>>>>>> Mike Parker wrote:
>>>>>>> Bill Baxter wrote:
>>>>>>>> Mike Parker wrote:
>>>>
>>>>>
>>>>> This is exactly what I was looking for. I don't understand it, but it works.
>>>>
>>>> Actually, it doesn't work.
>>>
>>> Ok, so in that case...
>>> I think you can put an alias for the type inside an interface, and use that to work around:
>>>
>>> interface Foo(T)
>>> {
>>> alias T TheType;
>>> void init(T);
>>> }
>>>
>>> ...
>>> static if ( is(U : Foo!(U.TheType)) ) {
>>> ...
>>> }
>>>
>>> That seems to work.
>>>
>>
>> Yes, this works. But, the static if evaluation never completes if U does not have TheType. It craps out with errors as soon as U.TheType is encountered rather than printing out the more friendly static assert.
>
> I don't understand. Can't you just make it
>
> static assert(is(U : Foo!(U.TheType))),
> "Use a Foo!() don't be a Foo! -- Mr. T");
Maybe you've found another bug?
Expressions inside an "is" should never cause an error unless they're syntactically mal-formed, so if you're saying you're getting an actual error from the expression inside the static assert then that's a problem.
But in that case I think you can work around with:
static if (is(U.TheType)) {
static assert(is(U : Foo!(U.TheType))),
"Use a Foo!() don't be a Foo! -- Mr. T");
} else {
static assert(false, "No .TheType so that can't be a Foo");
}
--bb
|
April 15, 2008 Re: Template Question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter wrote: > Bill Baxter wrote: >> Mike Parker wrote: >>> Bill Baxter wrote: >>>> Mike Parker wrote: >>>>> Mike Parker wrote: >>>>>> Bill Baxter wrote: >>>>>>> Mike Parker wrote: >>>>>>>> Bill Baxter wrote: >>>>>>>>> Mike Parker wrote: >>>>> >>>>>> >>>>>> This is exactly what I was looking for. I don't understand it, but it works. >>>>> >>>>> Actually, it doesn't work. >>>> >>>> Ok, so in that case... >>>> I think you can put an alias for the type inside an interface, and use that to work around: >>>> >>>> interface Foo(T) >>>> { >>>> alias T TheType; >>>> void init(T); >>>> } >>>> >>>> ... >>>> static if ( is(U : Foo!(U.TheType)) ) { >>>> ... >>>> } >>>> >>>> That seems to work. >>>> >>> >>> Yes, this works. But, the static if evaluation never completes if U does not have TheType. It craps out with errors as soon as U.TheType is encountered rather than printing out the more friendly static assert. >> >> I don't understand. Can't you just make it >> >> static assert(is(U : Foo!(U.TheType))), >> "Use a Foo!() don't be a Foo! -- Mr. T"); > > Maybe you've found another bug? > Expressions inside an "is" should never cause an error unless they're syntactically mal-formed, so if you're saying you're getting an actual error from the expression inside the static assert then that's a problem. It errors out with the following: Error: no property 'TheType' for type 'MyType' However, I finally worked out a semi-solution using the traits module. ======================================================================= private bool isFoo(T)() { // make sure this T is a class so that the error // is reported from here and not from tango.core.Traits. static if(is(T == class)) { BaseTypeTupleOf!(T) tup; static if(tup.length > 0) { static if(typeof(tup[0]).stringof ~ "(T)" == Foo.stringof) return true; } } return false; } class FooManager(T) { static if(!isFoo!(T)) static assert(0, "Mr. T ain't no Foo, Foo!"); } ======================================================================= Each element of the tuple /should/ be iterated and compared with Foo.stringof. I was under the impression that foreach could be used at compile time, but using it here causes compilation to fail, saying that isFoo can't be run at compile time. Changing Foo to an abstract class and always checking the first element of the Tuple works, but it will still break of the class hierarchy goes deeper than one level. |
April 15, 2008 Re: Template Question | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | BCS schrieb:
> Mike Parker wrote:
>> I've not worked much with templates in any language beyond the basics. Right now, I've got a problem that I've solved, but for which I'm looking a different solution.
>>
>> What I have is a templated interface like so:
>>
>> interface Foo(T)
>> {
>> void init(T);
>> void term();
>> void blah();
>> void bleh();
>> }
>>
>
> quick-n-dirty (and untested)
>
> interface FooBase{}
> interface Foo(T) : FooBase
> {
> void init(T);
> void term();
> void blah();
> void bleh();
> }
>
> then throw this in somewhere:
>
> static assert(is(T:FooBase));
While reading the posts of Mike and Bill above, i already wondered whether every Foo!(T) should be a subtype of Foo implicitly, so it would be possible to write "class Manager(U : Foo) {}"
Just a fix idea.
But if you can declare both Foo!(T) and Foo overloaded, FooBase could simply be renamed to Foo in the example above.
|
Copyright © 1999-2021 by the D Language Foundation