www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Trouble with template parameter matching

reply "tcak" <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
[code]
void func1(N)( const N name )
	if( is(N: string) || is(N: char[]) )
{
	func2( name );
}

void func2(N)( const N name )
	if( is(N: string) || is(N: char[]) )
{}

void main(){
	char[] blah = ['b', 'l', 'a', 'h'];

	func1( blah );
	//func1( "blah" );	// this works
}
[/code]

[result]
test.d(4): Error: template test.func2 cannot deduce function from 
argument types !()(const(char[])), candidates are:
test.d(7):        test.func2(N)(const N name) if (is(N : string) 
|| is(N : char[]))
[/result]

When func1 is called with blah variable, I assume that N is 
char[].

 From there, when func2 is called by func1, name should be 
const(char[]).

But since func2 defined name parameter with const, shouldn't the 
compiler accept const part of const(char[]) as func2's const, and 
accept N as char[] still?

Otherwise, it is being weirdly recursive, and requires casting.
Aug 02 2015
next sibling parent "Fusxfaranto" <fusxfaranto gmail.com> writes:
On Sunday, 2 August 2015 at 08:08:05 UTC, tcak wrote:
 [code]
 void func1(N)( const N name )
 	if( is(N: string) || is(N: char[]) )
 {
 	func2( name );
 }

 [...]
This seems like the reasonable behavior to me. Perhaps you should use Unqual? http://dlang.org/phobos/std_traits.html#Unqual
Aug 02 2015
prev sibling parent "anonymous" <anonymous example.com> writes:
On Sunday, 2 August 2015 at 08:08:05 UTC, tcak wrote:
 [code]
 void func1(N)( const N name )
 	if( is(N: string) || is(N: char[]) )
 {
 	func2( name );
 }

 void func2(N)( const N name )
 	if( is(N: string) || is(N: char[]) )
 {}

 void main(){
 	char[] blah = ['b', 'l', 'a', 'h'];

 	func1( blah );
 	//func1( "blah" );	// this works
 }
 [/code]

 [result]
 test.d(4): Error: template test.func2 cannot deduce function 
 from argument types !()(const(char[])), candidates are:
 test.d(7):        test.func2(N)(const N name) if (is(N : 
 string) || is(N : char[]))
 [/result]

 When func1 is called with blah variable, I assume that N is 
 char[].
Yup.
 From there, when func2 is called by func1, name should be 
 const(char[]).
Yup.
 But since func2 defined name parameter with const, shouldn't 
 the compiler accept const part of const(char[]) as func2's 
 const, and accept N as char[] still?
Nope. When removing the top level const of `const(char[])`, it becomes `const(char)[]`. Test for that in your template constraint and it works.
Aug 02 2015