www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Overload resolution for string

reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
My previous question was in the context of overloading opEquals. Here it 
is again in a simpler form.

void foo(const(char)[] s)
{}

void foo(const(wchar)[] s)
{}

void foo(const(dchar)[] s)
{}

void main()
{
     foo("hello");
}


Compilation error:

deneme.d(10024): Error: function deneme.foo called with argument types:
	((string))
matches both:
	deneme.foo(const(char)[] s)
and:
	deneme.foo(const(dchar)[] s)


Adding overloads for string, wstring, and dstring does not help. Same 
problem...

Replacing "hello" with either of "hello"c, "hello"w, or "hello"d fixes 
the issue.

This is a bug, right? I've been assuming that unqualified string 
literals were immutable char arrays, but the behavior is different 
between "hello" vs. "hello"c.

Am I missing something?

Thank you,
Ali
Apr 11 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 11 Apr 2010 15:33:09 -0400, Ali Çehreli <acehreli yahoo.com> wrote:

 This is a bug, right? I've been assuming that unqualified string  
 literals were immutable char arrays, but the behavior is different  
 between "hello" vs. "hello"c.

 Am I missing something?
"hello" is typed as a string *only* if you are using at a string. If you are using it as a wstring or a dstring, then it is typed that way. You can even use it as a const(char) * and it becomes an ASCII C-style string with a zero terminator! This way, you can do things like this without casts, conversions, or suffixes: dstring ds = "hello"; Unfortunately, this leads to the problem, what version of foo to call when supplied with just a literal? It can call all three! I don't like the implementation -- give an error -- but it's not an unreasonable choice. I'd file a bug and see what happens, perhaps Walter can change it. I'd recommend assuming the type that occurs when using auto. -Steve
Apr 11 2010
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Steven Schveighoffer wrote:
 On Sun, 11 Apr 2010 15:33:09 -0400, Ali Çehreli <acehreli yahoo.com> 
wrote:
 This is a bug, right? I've been assuming that unqualified string
 literals were immutable char arrays, but the behavior is different
 between "hello" vs. "hello"c.

 Am I missing something?
"hello" is typed as a string *only* if you are using at a string. If you are using it as a wstring or a dstring, then it is typed that way. You can even use it as a const(char) * and it becomes an ASCII C-style string with a zero terminator!
I did not know that. :) Could you please share some guidelines about chosing the type of the D-string to use at the interface... Should applications stick to one of these types and require callers to convert explicitly if needed? Should the common type be dstring? On the other hand, string seems to be a better choice because classes have the common toString member functions that return string. In my case, I have a set of classes that represent alphabet letters and alphabet strings. The motivation is to provide logical sorting and capitalization. (To me, even for the English alphabet, â should be sorted between a and b.) Since I want these types to be used as seamlessly as possibly, I wanted to provide opEquals overloads for char[], wchar[], and dchar[]. Should I not bother doing that? In fact, I really shouldn't due to this compiler error. Should my classes only interface with dchar and dstring? Thank you, Ali
Apr 11 2010
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 12 Apr 2010 00:40:44 -0400, Ali Çehreli <acehreli yahoo.com> wrote:

 Steven Schveighoffer wrote:
  > On Sun, 11 Apr 2010 15:33:09 -0400, Ali Çehreli <acehreli yahoo.com>  
 wrote:
  >
  >> This is a bug, right? I've been assuming that unqualified string
  >> literals were immutable char arrays, but the behavior is different
  >> between "hello" vs. "hello"c.
  >>
  >> Am I missing something?
  >
  > "hello" is typed as a string *only* if you are using at a string.  If
  > you are using it as a wstring or a dstring, then it is typed that way.
  > You can even use it as a const(char) * and it becomes an ASCII C-style
  > string with a zero terminator!

 I did not know that. :)

 Could you please share some guidelines about chosing the type of the  
 D-string to use at the interface...

 Should applications stick to one of these types and require callers to  
 convert explicitly if needed? Should the common type be dstring? On the  
 other hand, string seems to be a better choice because classes have the  
 common toString member functions that return string.

 In my case, I have a set of classes that represent alphabet letters and  
 alphabet strings. The motivation is to provide logical sorting and  
 capitalization. (To me, even for the English alphabet, â should be  
 sorted between a and b.)

 Since I want these types to be used as seamlessly as possibly, I wanted  
 to provide opEquals overloads for char[], wchar[], and dchar[]. Should I  
 not bother doing that? In fact, I really shouldn't due to this compiler  
 error.

 Should my classes only interface with dchar and dstring?
If you had to choose, I'd suggest choosing string. The reason is simple: auto s = "hello"; yourFunc(s); Because the compiler must choose a type when declaring s, it chooses string. I think perhaps the compiler should use the same rules when calling an overloaded function with a literal. You should file an enhancement request with bugzilla, see what Walter thinks. If he doesn't like the idea, he usually shoots it down pretty quick :) -Steve
Apr 12 2010