On Wednesday, August 03, 2016 09:21:13 Alex via Digitalmars-d-learn wrote: > On Monday, 1 August 2016 at 16:09:50 UTC, Alex wrote: > > On Monday, 1 August 2016 at 15:51:58 UTC, Jonathan M Davis > > wrote: > > template isIndexable(I, T) > > { > > > > enum isIndexable = __traits(compiles, T.init[I.init]); > > > > } > > As a last question afterwards: > Is it possible to create such an isIndexable template without > templating over the type T? > something like > > template isIndexable(I) > { > enum isIndexable = __traits(compiles, ???[I.init]); > } > > sure, I could use > > __traits(compiles, (int[]).init[I.init]) > > but is this the intended way to go?
__traits(compiles, ...) is testing whether the code in question compiles. What you need to test is whether the object is indexable by the other, and that would mean needing both the type being indexed and the type which is the index. Just because one particular type is indexable by whatever the index type is doesn't mean that another will be. For instance, int[] is only going to be indexable by size_t and anything that implicitly converts to size_t. Testing whether int[] is indexable with size_t isn't going to say anything about whether int[string] is indexable with size_t. If you want to test that int[string] is indexable with size_t, you'll need to actually test it with size_t, not int[] - the same goes for any other combinaton of object to index and object that is the index. If you're just typing out the whole thing every time, then you can do stuff like auto foo(I, T)(I index, T obj) if(__traits(compiles, obj[index])) { ... } because you have actual objects to deal with, whereas with a template written to encapsulate that test, you only have the types. The init property is just an easy way to get at an object of the type without declaring it or worrying about how one is constructed. But to do the same test as that example with a separate template, you're going to need both types. e.g. template isIndexable(I, T) { enum isIndexable = __traits(compiles, T.init[I.init]); } If you don't have both, you're not doing the same test, and it's impossible to test that one type is indexable by another without using both types in the test. To only have one of the two types in a test would be like trying t to test whether a function can be called on a particular type while only having the function in the test and not the type. It doesn't work. - Jonathan M Davis