List:MySQL++« Previous MessageNext Message »
From: Date:January 1 1970 12:00am
Subject:Re: [patch] row::operator[] - template version
View as plain text  
Chris Frey wrote:
> (btw, please feel free to reply to the list... I know the list config doesn't
> make that easy, but we need to have valuable input like yours archived) :-)

I'm used that in most other mailing lists reply replies to the list 
(here I need to "reply all", but I forget sometimes)

>>I had a similar problem where properties could be accessed by their 
>>indeces or by their names. My first solution was also like this: one of 
>>the functions is plain method and the other is templated. But I later 
>>found out that there were some problems with it - it just worked on some 
>>compilers (or something like this, not sure what the problem was 
>>exactly, but I had to redo it)
> 
> 
> I'd be interested in what kind of errors the above patch could cause.

I don't remember, but I really had to redo it :)

> I suppose the template/non-template could confuse some compilers.  If so,
> we could get rid of non-template members completely, and make a specialization
> for the const char * version.  That should work.

The problem is that there's no such thing as partial template 
specialization for members. If you have two templates with the same 
signature, there's good chance a wrong template gets selected (resulting 
in compile error or worse, wrong code being executed). For control of 
instantiation of templates SFINAE (substitution-failure-is-not-an-error) 
principle used. enable_if exploits this thing.

aproximately how it works:

template<bool B, class T> struct enableif{};
template<class T> struct enableif<true, T>{ typedef T type; };

template<class T> struct isint{ enum{ value= false};};
template<> struct isint<int>{ enum{ value= true};};

template<class T> struct isnotint{ enum{ value= true};};
template<> struct isnotint<int>{ enum{ value= false};};


struct test{
	template<class T>
	typename enableif<isint<T>::value, void>::type
		operator[](const T&){ cout << "int version\n"; }
	template<class T>
	typename enableif<isnotint<T>::value, void>::type
		operator[](const T&){ cout << "non-int version\n"; }
};
...
test x;
x[0];
x["dsds"];

but in this example long will be considered non-int also, unsigned int 
also etc (extra specializations are needed for long, char, and 
unsigned/signed versions).
Anyways boost::enable_if docs are worth to read to understad this 
better. ( http://tinyurl.com/d2pqk ) It will probably be included in the 
next cXX standard, as far as I'm concerned.

> 
> I haven't tried my patch on windows, so I don't know if there are funky
> errors there.  mysql++ can only be compiled on fairly recent compilers
> (VC7.0 doesn't even do it, so I hear), so maybe this is a non-issue, since
> all supported compilers may handle it.

The problem was not with the old compilers - on the other had I had 
problems only with some new I think (vc8 or g++34, not sure), anyways, 
most of my code barely/rarely compiles on 2.95 so I don't care for these 
compilers.
May be I'm little bit wrong about this problem for this case, as I 
recall there was a problem because my class was also templated and you 
cannot put specializations inside the class deffinition, but there were 
no way to do it outside of the class (specialization of templated class)

> Could you run a test compile and let us know, on WinXP?

I don't know how to compile it !!! :)
I'll look around for the patch on the list to be able to compile it, or 
I'll create my own project files from zero...

> 
> That's good, because I don't think we can, or want to, add boost to the
> build dependencies.
> 
> I'll have to read up on enable_if.  Some of the things that boost manages
> to do with C++ really surprise me.  I just looked at the new parameter
> library, and wow. :-)

all that stuff from boost are compile time only. probably it's not worth 
to make it depended on boost anyways :)), but it's ok to rip off that 
parts if needed, boost allows that

>>template<unsigned int N>
>>return_type operator[](const char(&a)[N]){ ... }
>>return_type operator[](unsigned int){ ... }
> 
> 
> This looks interesting, and similar to libpqxx, except for the templates.
> I think const char* behaviour is worth keeping though.


I just remebered, later I changed design and the need for templated 
version dissapeared I think :)
I wrote auxilary string class (str_range) that holds pointer and length 
(or pointer to the end, whatever).
it's automatically created from arrays and pointers (it has non-explicit 
constructors. For arrays it doesn't calculate the length)

and then I only had this:
ret_type operator[](int x){...}
ret_type operator[](const str_range& s){...}

and in case I used [0] then it would need to be converted from int to 
pointer, then from pointer to str_range. So I think compiler desided 
that it was easier to use int version :). Not sure if it's ok like this 
- but it worked in all the cases and all compilers I use.


I asked some question related a bit to that my problem, I found it on:
http://tinyurl.com/atonx

I think the problem was only related to my case where the class itself 
was templated and that caused the problem...
Thread
[patch] row::operator[] - template versionChris Frey18 Sep
  • Re: [patch] row::operator[] - template versionWarren Young19 Sep
    • Re: [patch] row::operator[] - template versionWarren Young19 Sep
      • Re: [patch] row::operator[] - template versionChris Frey19 Sep
        • Re: [patch] row::operator[] - template versionWarren Young19 Sep
          • Re: [patch] row::operator[] - template versionChris Frey19 Sep
Re: [patch] row::operator[] - template versionChris Frey18 Sep
  • Re: [patch] row::operator[] - template versionUnknown Sender18 Sep
    • Re: [patch] row::operator[] - template versionChris Frey18 Sep
      • Re: [patch] row::operator[] - template versionUnknown Sender18 Sep
        • Re: [patch] row::operator[] - template versionWarren Young19 Sep
          • Re: [patch] row::operator[] - template versionUnknown Sender19 Sep
            • Re: [patch] row::operator[] - template versionWarren Young19 Sep
      • Re: [OBORONA-SPAM] Re: [patch] row::operator[] - template versionUnknown Sender19 Sep
        • Re: [OBORONA-SPAM] Re: [patch] row::operator[] - template versionChris Frey19 Sep
          • Re: [patch] row::operator[] - template versionUnknown Sender19 Sep
            • Re: [patch] row::operator[] - template versionChris Frey19 Sep
            • Re: [patch] row::operator[] - template versionWarren Young19 Sep
        • Re: [patch] row::operator[] - template versionWarren Young19 Sep
    • Re: [patch] row::operator[] - template versionChris Frey18 Sep
  • Re: [patch] row::operator[] - template versionWarren Young19 Sep