www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Function constraint vs const parameter?

reply Jonathan Crapuchettes <jcrapuchettes gmail.com> writes:
I'm running into a problem with the following function definition when passing 
in a const(string[]).

public T condenseCountyList(T)(const T inputList) if (is(Unqual!T : string) || 
is(Unqual!T : string[]))

I'm getting the "Error: template common.condenseCountyList does not match any 
function template declaration" when calling the function as

condenseCountyList(countyList);

, but if I changed the calling code to

condenseCountyList(cast(string[])countyList)

dmd is happy.

How do I need to change the function constraint to make this work?

Thank you,
Jonathan Crapuchttes
Jun 06 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/06/2012 10:02 AM, Jonathan Crapuchettes wrote:
 I'm running into a problem with the following function definition when
 passing in a const(string[]).

 public T condenseCountyList(T)(const T inputList) if (is(Unqual!T :
 string) || is(Unqual!T : string[]))

 I'm getting the "Error: template common.condenseCountyList does not
 match any function template declaration" when calling the function as

 condenseCountyList(countyList);

 , but if I changed the calling code to

 condenseCountyList(cast(string[])countyList)

 dmd is happy.

 How do I need to change the function constraint to make this work?

 Thank you,
 Jonathan Crapuchttes
Sorry for being terse but this works: import std.traits; import std.array; template isSomeStringArray(T) { enum isSomeStringArray = is (typeof( { T variable; static assert (isSomeString!(typeof(variable.front))); }())); } T condenseCountyList(T)(const T inputList) if (isSomeString!T || isSomeStringArray!T) { return T.init; } void main() { auto countyList = [ "Santa Clara" ]; condenseCountyList(countyList); } isSomeString is defined in std.traits. isSomeStringArray above uses a number of D features: * anonymous delegate * executing that delegate by () (which is actually never executed) * typeof, which produces "invalid type" if the expression illegal * is, which produces true if the type that it receives is not invalid * eponymous templates Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
Jun 06 2012
parent reply Jonathan Crapuchettes <jcrapuchettes gmail.com> writes:
That worked great! I wish there was a simpler solution, but thank you very much 
for your help.
JC

Ali Çehreli wrote:
 On 06/06/2012 10:02 AM, Jonathan Crapuchettes wrote:
  > I'm running into a problem with the following function definition when
  > passing in a const(string[]).
  >
  > public T condenseCountyList(T)(const T inputList) if (is(Unqual!T :
  > string) || is(Unqual!T : string[]))
  >
  > I'm getting the "Error: template common.condenseCountyList does not
  > match any function template declaration" when calling the function as
  >
  > condenseCountyList(countyList);
  >
  > , but if I changed the calling code to
  >
  > condenseCountyList(cast(string[])countyList)
  >
  > dmd is happy.
  >
  > How do I need to change the function constraint to make this work?
  >
  > Thank you,
  > Jonathan Crapuchttes

 Sorry for being terse but this works:

 import std.traits;
 import std.array;

 template isSomeStringArray(T)
 {
 enum isSomeStringArray = is (typeof(
 {
 T variable;
 static assert (isSomeString!(typeof(variable.front)));
 }()));
 }

 T condenseCountyList(T)(const T inputList)
 if (isSomeString!T || isSomeStringArray!T)
 {
 return T.init;
 }

 void main()
 {
 auto countyList = [ "Santa Clara" ];
 condenseCountyList(countyList);
 }

 isSomeString is defined in std.traits. isSomeStringArray above uses a number of
 D features:

 * anonymous delegate

 * executing that delegate by () (which is actually never executed)

 * typeof, which produces "invalid type" if the expression illegal

 * is, which produces true if the type that it receives is not invalid

 * eponymous templates

 Ali
Jun 07 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/07/2012 12:02 PM, Jonathan Crapuchettes wrote:
 That worked great! I wish there was a simpler solution, but thank you
 very much for your help.
I am glad. :) Note that isSomeStringArray should have been named isSomeStringRange because it ensures that variable.front compiles. Since slices are ranges, it still works in your case.
 template isSomeStringArray(T)
 {
 enum isSomeStringArray = is (typeof(
 {
 T variable;
 static assert (isSomeString!(typeof(variable.front)));
 }()));
 }
Ali
Jun 07 2012