enum E { text1 = "text1", text2 = "text2", } enum E2 : string { text1 = "text1", text2 = "text2", } struct S { @safe: public: this(T)(T value) nothrow if (is(T == bool) || is(T == int) || is(T == string)) {} } void main() { int a = 1; // Not work //cannot deduce function from argument types !()(E) auto s = S(a == 1 ? E.text1 : E.text2); //cannot deduce function from argument types !()(E2) auto s2 = S(a == 1 ? E2.text1 : E2.text2); //work string t = a == 1 ? E.text1 : E.text2; auto s3 = S(t); }
E and E2 are different types from string, so when you check is(T == string), you're explicitly disallowing them. is(T1 == T2) is a lot stricter than calling fun(int) with a short value - it asks 'are these types the same type?', and E and string simply are not. You may have wanted to write is(T : string), which checks if E is implicitly convertible to string, which it is. This compiles and runs.