On Wednesday, 3 August 2016 at 14:23:59 UTC, Jonathan M Davis
wrote:
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
But it should.
Just found this:
https://www.sgi.com/tech/stl/StrictWeakOrdering.html
which should be fulfilled by a type, which can be used as a key.
So, in my opinion, the property "being a key" is a matter of an
abstract definition and should have nothing to do with objects
which I want to index with it.
Sure, the object which I want to index, has to define an opIndex
method, which can receive the key-thing, but this is already the
next step.