Re: Template function parameters

From: nevlis (silven_at_removesilven.canada.com)
Date: 09/27/04


Date: Mon, 27 Sep 2004 15:53:58 GMT


"Doug Harrison [MVP]" <dsh@mvps.org> wrote in
news:opagl0puoccecajsqq7sc39rpejoidlcr8@4ax.com:

> nevlis wrote:
>
>>I am trying to create a Template function that will take
>>differnet parameter types. However all my attempts have failed
>>can someone please tell me what I am doing wrong here is the code.
>>
>>It seems to work when I pass integers however will not compile when
>>I have a float or double
>>
>>I get this error when compiling
>>
>>initializing : cannot convert from 'unsigned short *' to 'double'
>>
>>I do not understand why it has unsigned short when I am passing
>>a double for the intData parameters
>>
>>
>>//function prototype
>>template <class Z>void StoreInArray(VARIANT* arr_rgElems,const
>>inDataType, Z inData, int intPosition);
>>
>>//Test Calling this works
>>strcpy (strAsterisk, "*");
>>strTemp = A2BSTR(strAsterisk);
>>StoreInArray(rgElems,VT_BSTR, strTemp, intCounter++);
>>
>>//this works
>>StoreInArray(rgElems,VT_I2, 99, intCounter++);
>>
>>//I tried different many differnet ways but always get
>>//the same type of error when compiling
>>
>>double tempX = 8.99
>>StoreInArray<double>(rgElems,VT_R8, tempX, intCounter++);
>>StoreInArray<double>(rgElems,VT_R8, (double)tempX, intCounter++);
>>StoreInArray(rgElems,VT_R8, (double)tempX, intCounter++);
>>
>>
>>//function
>>template <class Z> void StoreInArray(VARIANT* arr_rgElems,const
>>inDataType, Z inData, int intPosition){
>
> Note that implicit int is not legal, so that should be "const int",

//int should be integer here

> not just "const".
>
>> COleDateTime myDateTime;
>>
>> double douInData = inData;
>
> The statement above is flawed, and I don't see how the compiler can
> possibly accept your earlier call where Z is BSTR. It would be helpful
> to know what compiler version you're using, and it would be even more
> helpful if you were to present this as a small console program
> fragment that can be compiled and which demonstrates the problem. Get
> rid of all the irrelevant things like BSTR, COleDateTime, etc and
> write it in terms of basic types.

//compiler version VC++ 6

>
> You should not be converting inData to some other type, only to
> convert it back below. It won't work for non-arithmetic types like
> pointers, and it can lose precision for 64 bit integer types. You'd be
> better off forgetting about templates and making inData void*, passing
> objects by address and casting to the correct type with, for example:
>
> // inData now void*
> arr_rgElems[intPosition].intVal = *(int*) inData;
>
>> VariantInit(&arr_rgElems[intPosition]);
>> arr_rgElems[intPosition].vt = inDataType;
>> switch (inDataType) {
>> case VT_BSTR:
>> arr_rgElems[intPosition].bstrVal = (BSTR) inData;
>> break;
>>
>> case VT_I2:
>> arr_rgElems[intPosition].intVal = (int)inData;
>> break;
>>
>> case VT_I4:
>> arr_rgElems[intPosition].intVal = (long)inData;
>> break;
>>
>> case VT_R4:
>> arr_rgElems[intPosition].fltVal = (float)inData;
>> break;
>>
>> case VT_R8:
>> arr_rgElems[intPosition].dblVal = (double)inData;
>> break;
>>
>> case VT_DATE:
>> myDateTime = (time_t) *(long*)inData;
>> arr_rgElems[intPosition].date = (DATE)myDateTime;
>> break;
>>
>> default:
>> break;
>> }
>>}
>
> When all is said and done, I just don't see the advantage in making
> this function a template. I could see writing a bunch of overloaded
> functions to relieve you from having to specify the VT_xxx type,
> though, and they could be one-liners that defer to the generic form
> that takes the VT_xxx type and void*.
>

Hi Doug,

Thanks for the quick response... To begin let me just say that I do not
use C++ or C very often so forgive me if some things are not correct.

My origninal function was

void StoreInArray(VARIANT* arr_rgElems,const inDataType, void* inData,
int intPosition){

//I will change int to integer

COleDateTime myDateTime;
        
        VariantInit(&arr_rgElems[intPosition]);
        arr_rgElems[intPosition].vt = inDataType;
        switch (inDataType) {
                case VT_BSTR:
                        arr_rgElems[intPosition].bstrVal = (BSTR) inData;
                        break;

                case VT_I2:
                        arr_rgElems[intPosition].intVal = *(int*)inData;
                        break;

                case VT_I4:
                        arr_rgElems[intPosition].intVal = *(long*)inData;
                        break;

                case VT_R4:
                        arr_rgElems[intPosition].fltVal = *(float*)inData;
                        break;

                case VT_R8:
                        arr_rgElems[intPosition].dblVal = *(double*)inData;
                        break;

                case VT_DATE:
                        myDateTime = (time_t) *(long*)inData;
                        arr_rgElems[intPosition].date = (DATE)myDateTime;
                        break;

                default:
                        break;
        }
}

Here was my orginal funtion so I guess I will stick to it... I will look
into overloading the function as you mentionned.

I guess my attempt to use my first template should not have been here.

Thanks nevlis



Relevant Pages

  • Re: Template function parameters
    ... >differnet parameter types. ... >inDataType, Z inData, int intPosition){ ... and I don't see how the compiler can possibly ...
    (microsoft.public.vc.language)
  • Re: OOP and OOD for senior C-style embedded software engineers
    ... metaprogramming in C++ to whole different level using the template ... templates let the compiler do more work ... The worst thing is when a function throws an exception ... And of course, exception specifications should work like people think they work, not as they /do/ work. ...
    (comp.arch.embedded)
  • Re: OOP and OOD for senior C-style embedded software engineers
    ... metaprogramming in C++ to whole different level using the template ... In particular, templates let the compiler do more work at compile time, and save the target from work at run time. ... Templates can be great for generic libraries, and do not necessarily create code bloat. ... You can use RAII even without exceptions, but obviously you have to handle your errors explicitly. ...
    (comp.arch.embedded)
  • Re: [C++] Vector - guaranteed to be contiguous?
    ... >> member is templated on the input iterators as well. ... template<typename OUTITER, typename INITER, typename INITERT> ... What happens is that the compiler sees copy and thinks, "Hey, I know copy. ... But it is a template, let me try to deduce those types. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: generic programming is very powerful. c should support it
    ... Where the compiler matches the correct template. ... already happens differently on different implementations. ...
    (comp.lang.c)