digitalmars.D.learn - is(some template instantiation) is true, but the actual instantiation
- Adrian Matoga (19/19) Jan 29 2016 Code:
- Basile B. (12/13) Jan 29 2016 You can use a constraint to prevent invalid instantiation:
- Steven Schveighoffer (4/23) Jan 29 2016 is(T) is supposed to be false if T is not a valid type.
- Adrian Matoga (14/46) Jan 29 2016 Oh, there's more:
- Basile B. (6/28) Jan 29 2016 Haven't you seen my answer about constraint ?
- Steven Schveighoffer (7/12) Jan 29 2016 A constraint should not be necessary here. Constraints are useful when
- Adrian Matoga (7/12) Jan 30 2016 Yes, I've seen it, thanks.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/16) Jan 29 2016 As I noted on the bug report, they are work when moved from module scope...
- Adrian Matoga (2/7) Jan 30 2016 Thanks a lot! Now I can continue my work. :)
Code: ---- struct HasFoo { void foo() {} } struct NoFoo {} struct CallsFoo(T) { T t; void bar() { t.foo(); } } static assert(is(CallsFoo!HasFoo)); alias Bar = CallsFoo!HasFoo; static assert(is(CallsFoo!NoFoo)); // (1) //alias Baz = CallsFoo!NoFoo; // (2) ---- This compiles, although I expected that (1) should fail. Now try uncommenting (2) and it can't be compiled. Why does `is(CallsFoo!NoFoo)` evaluate to true if `is(CallsFoo!NoFoo)` can't be instantiated? Am I missing something about `is(T)` or is it a bug? How can I reliably test if CallsFoo can be instantiated?
Jan 29 2016
On Friday, 29 January 2016 at 15:28:29 UTC, Adrian Matoga wrote:How can I reliably test if CallsFoo can be instantiated?You can use a constraint to prevent invalid instantiation: struct HasFoo { void foo() {} } struct NoFoo {} struct CallsFoo(T) if (__traits(hasMember, T, "foo")) { T t; void bar() { t.foo(); } } static assert(is(CallsFoo!HasFoo)); static assert(!is(CallsFoo!NoFoo));
Jan 29 2016
On 1/29/16 10:28 AM, Adrian Matoga wrote:Code: ---- struct HasFoo { void foo() {} } struct NoFoo {} struct CallsFoo(T) { T t; void bar() { t.foo(); } } static assert(is(CallsFoo!HasFoo)); alias Bar = CallsFoo!HasFoo; static assert(is(CallsFoo!NoFoo)); // (1) //alias Baz = CallsFoo!NoFoo; // (2) ---- This compiles, although I expected that (1) should fail. Now try uncommenting (2) and it can't be compiled. Why does `is(CallsFoo!NoFoo)` evaluate to true if `is(CallsFoo!NoFoo)` can't be instantiated? Am I missing something about `is(T)` or is it a bug? How can I reliably test if CallsFoo can be instantiated?is(T) is supposed to be false if T is not a valid type. I would agree with you that the static assert should fail. -Steve
Jan 29 2016
On Friday, 29 January 2016 at 16:36:01 UTC, Steven Schveighoffer wrote:On 1/29/16 10:28 AM, Adrian Matoga wrote:Oh, there's more: // this should fail: static assert(is(CallsFoo!NoFoo)); // this should fail too: static assert(is(typeof({ alias Baz = CallsFoo!NoFoo; return Baz.init; }()))); // and this: static assert(__traits(compiles, { alias Baz = CallsFoo!NoFoo; return Baz.init; }())); // but only this fails: alias Baz = CallsFoo!NoFoo; https://issues.dlang.org/show_bug.cgi?id=15623Code: ---- struct HasFoo { void foo() {} } struct NoFoo {} struct CallsFoo(T) { T t; void bar() { t.foo(); } } static assert(is(CallsFoo!HasFoo)); alias Bar = CallsFoo!HasFoo; static assert(is(CallsFoo!NoFoo)); // (1) //alias Baz = CallsFoo!NoFoo; // (2) ---- This compiles, although I expected that (1) should fail. Now try uncommenting (2) and it can't be compiled. Why does `is(CallsFoo!NoFoo)` evaluate to true if `is(CallsFoo!NoFoo)` can't be instantiated? Am I missing something about `is(T)` or is it a bug? How can I reliably test if CallsFoo can be instantiated?is(T) is supposed to be false if T is not a valid type. I would agree with you that the static assert should fail. -Steve
Jan 29 2016
On Friday, 29 January 2016 at 17:01:46 UTC, Adrian Matoga wrote:On Friday, 29 January 2016 at 16:36:01 UTC, Steven Schveighoffer wrote:Haven't you seen my answer about constraint ? If you put a constraint on your function template then invalid instantiations are rejected. I mean... this language feature is not just ornamental... What do you think constraints are used for otherwise ^^On 1/29/16 10:28 AM, Adrian Matoga wrote:Oh, there's more: // this should fail: static assert(is(CallsFoo!NoFoo)); // this should fail too: static assert(is(typeof({ alias Baz = CallsFoo!NoFoo; return Baz.init; }()))); // and this: static assert(__traits(compiles, { alias Baz = CallsFoo!NoFoo; return Baz.init; }())); // but only this fails: alias Baz = CallsFoo!NoFoo; https://issues.dlang.org/show_bug.cgi?id=15623[...]is(T) is supposed to be false if T is not a valid type. I would agree with you that the static assert should fail. -Steve
Jan 29 2016
On 1/29/16 6:44 PM, Basile B. wrote:Haven't you seen my answer about constraint ? If you put a constraint on your function template then invalid instantiations are rejected. I mean... this language feature is not just ornamental... What do you think constraints are used for otherwise ^^A constraint should not be necessary here. Constraints are useful when you have multiple templates that may match (without specializations), or you want to affect the way the compiler reports errors. Iff a template instantiation T compiles, then is(T) should evaluate to true. At least, that's my understanding. -Steve
Jan 29 2016
On Friday, 29 January 2016 at 23:44:56 UTC, Basile B. wrote:Haven't you seen my answer about constraint ? If you put a constraint on your function template then invalid instantiations are rejected. I mean... this language feature is not just ornamental... What do you think constraints are used for otherwise ^^Yes, I've seen it, thanks. Requiring the user to write the constraint might indeed enforce a better style, but I want to be able to test it even if the user forgets the constraint. Otherwise she'll get cryptic error messages from some other code assuming that CallsFoo!NoFoo is a valid type.
Jan 30 2016
On 01/29/2016 09:01 AM, Adrian Matoga wrote:Oh, there's more: // this should fail: static assert(is(CallsFoo!NoFoo)); // this should fail too: static assert(is(typeof({ alias Baz = CallsFoo!NoFoo; return Baz.init; }()))); // and this: static assert(__traits(compiles, { alias Baz = CallsFoo!NoFoo; return Baz.init; }())); // but only this fails: alias Baz = CallsFoo!NoFoo; https://issues.dlang.org/show_bug.cgi?id=15623As I noted on the bug report, they are work when moved from module scope to inside a function (e.g. main()). At least there's that workaround... Ali
Jan 29 2016
On Saturday, 30 January 2016 at 00:16:21 UTC, Ali Çehreli wrote:Thanks a lot! Now I can continue my work. :)https://issues.dlang.org/show_bug.cgi?id=15623As I noted on the bug report, they are work when moved from module scope to inside a function (e.g. main()). At least there's that workaround... Ali
Jan 30 2016