digitalmars.D - Templates, implicit conversions and const
- Regan Heath (39/39) Jul 09 2007 The 2nd thing which irritated me a little over the weekend was how
- Kirk McDonald (12/67) Jul 09 2007 Re-write the function as:
- Regan Heath (5/13) Jul 10 2007 Good point, why didn't I think of that.
The 2nd thing which irritated me a little over the weekend was how templates and const can interact. For example: bool contains(T)(T[] array, T value) { foreach(v; array) if (v == value) return true; return false; } void foo(const(char) c) {} void main() { string tests = "test"; char[] testc = tests.dup; tests.contains(cast(const(char))'a'); contains!(const(char))(tests, 'a'); testc.contains('a'); foo('a'); } The cast in the first contains call is required, without it we get the error: C:\D\src\tmp\tplconst.d(14): template tplconst.contains(T) cannot deduce template function from argument types (const(char)[],char) The available templates are: (const(char)[],const(char)) (char[],char) And looking at the template argument deduction rules I can see why it cannot find a match. T is found to be both 'const(char)' and 'char'. But, I wonder if it should then apply the standard function overloading rule: "In D, function overloading is simple. It matches exactly, it matches with implicit conversions, or it does not match. If there is more than one match, it is an error." If it performed implicit conversion on 'char' it could get 'const(char)' and would therefore match the template: (const(char)[],const(char)) It cannot implcitly convert 'const(char)[]' to 'char[]' so it will never match the other option. Thoughts? Regan
Jul 09 2007
Regan Heath wrote:The 2nd thing which irritated me a little over the weekend was how templates and const can interact. For example: bool contains(T)(T[] array, T value) { foreach(v; array) if (v == value) return true; return false; } void foo(const(char) c) {} void main() { string tests = "test"; char[] testc = tests.dup; tests.contains(cast(const(char))'a'); contains!(const(char))(tests, 'a'); testc.contains('a'); foo('a'); } The cast in the first contains call is required, without it we get the error: C:\D\src\tmp\tplconst.d(14): template tplconst.contains(T) cannot deduce template function from argument types (const(char)[],char) The available templates are: (const(char)[],const(char)) (char[],char) And looking at the template argument deduction rules I can see why it cannot find a match. T is found to be both 'const(char)' and 'char'. But, I wonder if it should then apply the standard function overloading rule: "In D, function overloading is simple. It matches exactly, it matches with implicit conversions, or it does not match. If there is more than one match, it is an error." If it performed implicit conversion on 'char' it could get 'const(char)' and would therefore match the template: (const(char)[],const(char)) It cannot implcitly convert 'const(char)[]' to 'char[]' so it will never match the other option. Thoughts? ReganRe-write the function as: bool contains(T, U)(T[] array, U value) { foreach(v; array) if (v == value) return true; return false; } You can still compare a const(char) and a char for equality. -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Jul 09 2007
Kirk McDonald wrote:Re-write the function as: bool contains(T, U)(T[] array, U value) { foreach(v; array) if (v == value) return true; return false; } You can still compare a const(char) and a char for equality.Good point, why didn't I think of that. Regardless I think it would be nice if templates applied implicit conversions to find matches. Regan
Jul 10 2007