CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Feb 2003
    Location
    London, UK
    Posts
    23

    Unhappy global template function problem

    Hi there,

    I am trying to provide a global function to be used in quite a few classes but I just keep getting linker errors (this is using gcc).
    My header file looks like this:
    //A simple streamcasting TEMPLATE function

    #ifndef _STREAMCAST_H_
    #define _STREAMCAST_H_

    #include <strstream>
    #include <iostream>


    template <class Type>
    std::string stream_cast( Type const& );

    #endif

    and my source file like this:
    #include "stream_cast.h"
    #include <strstream>
    #include <iostream>

    using namespace std;

    template <class Type>
    string stream_cast( Type const& from )
    {
    strstream stream;
    string to;
    stream << from;
    stream >> to;
    return to;
    }

    I seem to get linker errors if I try to call this function even though I am definitely including the header file. Examples of linker error:
    This line (where i is an unsigned int):

    plot_command+=", \'\' u 1:"+stream_cast(i+1);

    produces this

    ld: Undefined symbols:
    std::basic_string<char, std::char_traits<char>, std::allocator<char> > stream_cast<unsigned>(unsigned const&)

    AND (where example is a double)
    string title;
    title=title+stream_cast(example);

    produces this

    ld: Undefined symbols:
    stream_cast(double const&)

    Its weird because it works fine if you include it in one of the class source files and only call it from that source file.

    Thanks

  2. #2
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    You need to inline all the template code in the header file.

    Jeff

  3. #3
    Join Date
    Feb 2003
    Location
    London, UK
    Posts
    23
    OK.
    I have tried that but I still get the same results.
    I have made my source file blank and changed my header file to:

    #ifndef _STREAMCAST_H_
    #define _STREAMCAST_H_

    #include <strstream>
    #include <iostream>


    template <class Type>
    inline std::string stream_cast( Type const& from)
    {
    std::strstream stream;
    std::string to;
    stream << from;
    stream >> to;
    return to;
    }
    #endif

    But the same problems arise. Interestingly if in the first example i gave I change an unsigned int to an int it seems to work, but still fails with the double.

    very confusing

  4. #4
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    This works on VC++ 6.0:

    Code:
    #include <strstream>
    #include <iostream>
    #include <string>
    
    template <class Type>
    inline std::string stream_cast( Type const& from)
    {
    	std::strstream stream;
    	std::string to;
    	stream << from;
    	stream >> to;
    	return to;
    }
    
    int main()
    {
    	double d = 2.5;
    	std::cout << stream_cast(d);
    	return 0;
    }
    Make sure you don't have the orginal source file in the project and make sure everyting relying on the header file is rebuilt.

    Jeff

  5. #5
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    Slightly simpler version:
    Code:
    template <class Type>
    inline std::string stream_cast( Type const& from)
    {
    	std::strstream stream;
    	stream << from;
    	return stream.str();
    }
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  6. #6
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    Just a small note, if your compiler supports it you should
    use stringstream instead. strstream is deprecated.

  7. #7
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    I may be wrong about this ... but I believe that strstream::str()
    returns a char* that won't be delete'd unless the programmer
    calls freeze before the strstream object goes out of scope.
    It has some weird behavior like that ... and that's just one of the
    many reasons that people recommend you use stringstream

  8. #8
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    According to Josuttis, strstream::str() calls the member function
    freeze() implicitly. However, it does not automatically
    append a string termination character ('\0') - you need
    to do it explicitly (std::ends)

  9. #9
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Yeah that's it :) On that same page [650] check out #1:
    Beause ownership of the memory is transferred to the caller,
    unless the stream was initialized with a buffer of fixed size, the
    character sequence has to be released. However, there is no
    guarantee how the memory was allocated, thus is is not always
    safe to release it using delete[]. Your best bet is to return the
    memory to the stream by calling the member function freeze()
    with the argument false
    This is what strstream does NOT do. Josuttis gives some
    examples for strstream usage:

    Code:
    std::ostrstream buffer;
    buffer << "float X: " << x << std::ends;
    char* s = buffer.str();
    foo(s);
    
    buffer.freeze(false);
    Without that buffer.freeze(false), there would be a memory leak.
    That's all I was really implying in my last post. This only helps to
    reinforce your and Graham's argument to not use strstream :)

    --Paul

  10. #10
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    Actually, I think I was being slack and meant std::ostringstream. std::ostringstream::str() returns a std::string, of course. In my defence, I've been out of work for a while now, so my reference sources are a bit thin.....
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  11. #11
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    I'm sorry. I wasn't trying to make light of your post or anything;
    I was just telling the original poster about the disadvantages of
    strstream. Anyway, it's all water under the bridge now

    --Paul

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