Thread overview
Function constraint vs const parameter?
Jun 06, 2012
Ali Çehreli
Jun 07, 2012
Ali Çehreli
June 06, 2012
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
June 06, 2012
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

June 07, 2012
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
>
June 07, 2012
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