CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    Join Date
    May 2002
    Location
    Nuremberg, Germany
    Posts
    34

    Problem with function template

    Hi!

    I got a problem related to templates, something is not quite working the way it should:

    template <int SIZE> void Func( void )
    {
    cout << SIZE << endl;
    }

    int main( void )
    {
    Func<2>();

    Func<8>();
    }

    The output I get is

    8
    8

    and I don't understand why. Shouldn't it be
    2
    8

    as a separate function should be created for each call ???

  2. #2
    Join Date
    Aug 2001
    Location
    Germany
    Posts
    166
    try this...
    Code:
    template <class TYPE> void Func(const TYPE& t)
    {
    	cout << t << endl;
    }
    
    int main(int argc, char* argv[])
    {
    	Func<int>(2);
    	Func<int>(8);
    
    	return 0;
    }
    Mikey

  3. #3
    Join Date
    May 2002
    Location
    Nuremberg, Germany
    Posts
    34
    Well thanks, but this does not solve my original problem. Consider the following code:

    Code:
    class CAllocator
    {
    public:
        CAllocator( size_t size ) : m_size( size ) {}
        ~CAllocator() {};
    
    private:
        size_t m_size;
    };
    
    template <size_t SIZE> CAllocator& GetAllocator( void )
    {
        static CAllocator   inst( SIZE );
    
        return inst;
    }
    
    int main( void )
    {
        GetAllocator<2>();
    
        GetAllocator<8>();
    
        return 0;
    }
    I need a SEPARATE function to be created for each call to GetAllocator() with a certain size. The idea is to have one CAllocator object for each size, the above code always uses the same function, hence there is only one static CAllocator object, but I need several!

  4. #4
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Hello,

    What compiler do you have? On Visual Studio .NET, the result is
    what you originally expected [I've since uninstalled Visual Studio
    6 so I cannot test this code there]. My guess is that it's your
    compiler's support for function templates [something Visual
    Studio 6.0 wasn't all that great with, which is why I assumed
    that]. Anyway, if you DO have Visual Studio 6, make sure that
    you have the latest service pack [Service Pack 5].

    Edit: Oops, I still have Visual Studio 6.0 installed on another
    computer here and I tested the code; it doesn't work even with
    Service Pack 5 so you're just plain out of luck unless you upgrade
    the compiler. It's time for workarounds :P

    --Paul

  5. #5
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    This does work, and might be a good workaround:

    Code:
    #include <iostream>
    
    template<int SIZE>
    class Test
    {
    public:
    	operator()()
    	{
    		std::cout << SIZE << std::endl;
    	}
    };
    
    int main()
    {
    	Test<5>()();
    	Test<8>()();
    	std::cin.get();
    	return 0;
    }
    Jeff

  6. #6
    Join Date
    May 2002
    Location
    Nuremberg, Germany
    Posts
    34
    @Paul: Yes, you're right, I use Visual C++ 6.0 and whenever I had a problem it was with templates... I hope there is a cheap upgrade to .net... Anyway, I am glad to hear that it's the compilers fault, not that I'm stoopid or so...

    @ jfaust: The workaround looks like it could work, great idea anyway, thanks!

  7. #7
    Join Date
    Aug 2001
    Location
    Germany
    Posts
    166
    Eisenbart
    ...
    static CAllocator inst( SIZE );
    ...
    but your static CAllocator will not get more instances eventhough it's in a template-class...

    Mikey

  8. #8
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Originally posted by Mikey
    Eisenbart

    but your static CAllocator will not get more instances eventhough it's in a template-class...

    Mikey
    Actually it will:
    Code:
    #include <iostream>
    using namespace std;
    
    class CAllocator
    {
    public:
        CAllocator( size_t size ) : m_size( size ) 
        {
           cout << "CAllocator::CAllocator(" << size << ")" << endl;
        }
        ~CAllocator() {};
    
    private:
        size_t m_size;
    };
    
    template <size_t SIZE> CAllocator& GetAllocator( void )
    {
        static CAllocator   inst( SIZE );
    
        return inst;
    }
    
    int main( void )
    {
        GetAllocator<2>();
        GetAllocator<8>();
    
        return 0;
    }
    Output:
    CAllocator::CAllocator(2)
    CAllocator::CAllocator(8)
    Remember, templates actually generate code. Because his
    function is templatized, it'll get generated for each template
    parameter that's passed into it. It's similar to having a function
    overloaded for an int and a char; the compiler also "overloads"
    with template parameters.

    --Paul

  9. #9
    Join Date
    Aug 2001
    Location
    Germany
    Posts
    166
    Originally posted by PaulWendt
    Actually it will (...) Because his function is templatized, it'll get generated for each template parameter that's passed into it.
    Paul, I copied Your code 1:1 to VC6.
    The constructor of CAllocator is only called once and the returned ref.-addresses by GetAllocator<2>() and GetAllocator<8>() are the same.

    Though, in VC.NET it's called twice - so it depence on the compiler You use, resp. could be a bug in VC6.

    Mikey
    Last edited by Mikey; December 8th, 2002 at 11:34 AM.

  10. #10
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    GetAllocator<2>() and GetAllocator<8>() are distinct functions, and the static members should also be distinct. This is a bug in VC6. It's nice to hear they've corrected this in .net.

    Jeff

  11. #11
    Join Date
    Aug 2001
    Location
    Germany
    Posts
    166
    seems to be a heavy bug in VC6!

    replacing PAUL's main()-function with this:
    Code:
    int main( void )
    {
    	CAllocator* pAlloc_1=NULL, *pAlloc_2=NULL;
    
    	pAlloc_1 = &GetAllocator<2>();
    	pAlloc_2 = &GetAllocator<8>();
    
    	cout << endl << "Addresses:" << endl;
    	cout << pAlloc_1 << endl;
    	cout << pAlloc_2 << endl;
    
    	getch();
    	return 0;
    } 
    Output:
    
    CAllocator::CAllocator(8)
    
    Addresses:
    0047DB2C
    0047DB2C
    If You comment out

    pAlloc_2 = &GetAllocator<8>();

    the output is

    CAllocator::CAllocator(2)!

  12. #12
    Join Date
    May 2002
    Location
    Nuremberg, Germany
    Posts
    34
    Yes, it is a bug in VC++ 6.0. I have just downloaded a trial version of the Intel C++ compiler V7.0, and the same code behaves very different there - to be more precise, it works the way it should!

    Looks like I should get a new compiler. Intel's compiler seems nice, it also appears to produce faster code, though I haven't really tested it yet...

    On the other hand, it does not support all the features I want, at least it does not support the 'export' keyword that can be used with templates...

    Some of you seem to possess VC.net - can you tell me wether it supports the 'export' keyword, thus providing for more ansi compliance?

    Both VC++ 6.0 and Intel C++ 7.0 reject the following code

    Code:
    export template<class T>
    class CSomething
    {
    
    };
    because of the 'export' keyword.

  13. #13
    Join Date
    Aug 2001
    Location
    Germany
    Posts
    166

    No,

    export template<class T>
    Your code doesn't work in vc.net, also.
    Last edited by Mikey; December 8th, 2002 at 05:39 PM.

  14. #14
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    The only compiler I know of that supports 'export' is the Comeau compiler. A recent article by Herb Sutter describes that this doesn't really gain you that much anyway. In other words, you still need to inline your templates.

    Jeff

  15. #15
    Join Date
    May 2002
    Location
    Nuremberg, Germany
    Posts
    34
    Well, I didn't expect to gain performance or whatsoever, but it better fits my programming style - it sounds childish, but I want .cpp and .h files to come in pairs...

    You do not necessarily have to inline the templates, you just have to put everything into the header files.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured