hi

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Nov 2008
Posts: 3
Reputation: sagar_d is an unknown quantity at this point 
Solved Threads: 0
sagar_d sagar_d is offline Offline
Newbie Poster

hi

 
0
  #1
Nov 10th, 2008
  1. template <class T>
  2. void trace(LogBuffer& msgBuffer, T& data)
  3. {
  4. data.trace(msgBuffer);
  5. }
In the above template fuction we are using a generic class T, but when we are compiling on gcc4.1.3 compiler we ar getting the following error.

error:request for member 'trace' in 'data', which is of non-class type 'std::ios_base& ()(std::ios_base&)

The trace function is being called in some other file as shown below

  1. template <class T>
  2. LogBuffer& LogBuffer::operator<<(T & data)
  3. {
  4. trace(*this, data); // trace fuction called here
  5. return *this;
  6. }

We found that the above piece of code compiles fine on older version of gcc compiler like 2.9.


//Trace functions. These are the trace functions called form here we able to call different trace functions of different classes (due to the template deceleration)
//Again these trace functions are at different class of different files.
// here past compiler simply forget the problem of generic type. But GCC 4.1.2 compiler very much specific about this generic types.
// I hope that u can understand with this info..

this is the class which we have

  1. class LogBuffer
  2. {
  3. public:
  4.  
  5. LogBuffer(LogFactor& logFactor);
  6. ~LogBuffer();
  7.  
  8. uint8_t* GetStart();
  9. size_t GetProcessedSize();
  10.  
  11. void Flush();
  12. void SetFormat(ios::fmtflags flags, ios::fmtflags mask);
  13. uint8_t GetIndent();
  14. void SetIndent(uint8_t indent);
  15.  
  16.  
  17.  
  18. // Generic flat type
  19. template <class T>
  20. LogBuffer& operator<<(T& data);
  21.  
  22. // Single element pointer
  23. template <class T>
  24. LogBuffer& operator<<(T* & data);
  25.  
  26. // Array
  27. template <class T>
  28. LogBuffer& operator<<(const MsgBufferArray<T>& data);
  29.  
  30.  
  31. protected:
  32. void SetDefaultFormat();
  33.  
  34. LoggerFunctor& _functor;
  35. ostringstream _buffer;
  36. uint8_t _indent;
  37. };

and also that some of the definitions at different file are available in the frm of class members.
This template function is unable to resolve the type.



any suggestions....
|
Last edited by Ancient Dragon; Nov 10th, 2008 at 9:26 am. Reason: add code tags
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 973
Reputation: Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough 
Solved Threads: 107
Alex Edwards's Avatar
Alex Edwards Alex Edwards is offline Offline
Posting Shark

Re: hi

 
0
  #2
Nov 10th, 2008
I tried to remake the program and provide examples in an attempt to reproduce the problem on Microsoft Visual C++ 2005/2008 compiler, but I different errors than the one I expected despite the tests--

Similar Problem here

  1. /**
  2.  * Assumed header file for LogBuffer
  3.  */
  4. #ifndef LOGBUFFER_H
  5. #define LOGBUFFER_H
  6.  
  7. #include <iostream>
  8.  
  9. /* Dummy values */
  10. typedef char LogFactor;
  11. typedef int uint8_t;
  12. template<class T>class MsgBufferArray;
  13. typedef char LoggerFunctor;
  14. typedef char ostringstream;
  15.  
  16. using std::ios;
  17.  
  18. namespace Log{
  19.  
  20. class LogBuffer;
  21.  
  22. template <class T>
  23. void trace(LogBuffer& msgBuffer, T& data);
  24.  
  25. class LogBuffer{
  26.  
  27. public:
  28. LogBuffer(LogFactor& logFactor);
  29. ~LogBuffer();
  30.  
  31. uint8_t* GetStart();
  32. size_t GetProcessedSize();
  33.  
  34. void Flush();
  35. void SetFormat(ios::fmtflags flags, ios::fmtflags mask);
  36. uint8_t GetIndent();
  37. void SetIndent(uint8_t indent);
  38.  
  39.  
  40. // Generic flat type
  41. template <class T>
  42. LogBuffer& operator<<(T& data);
  43.  
  44. // Single element pointer
  45. template <class T>
  46. LogBuffer& operator<<(T* & data);
  47.  
  48. // Array
  49. template <class T>
  50. LogBuffer& operator<<(const MsgBufferArray<T>& data);
  51.  
  52.  
  53. protected:
  54. void SetDefaultFormat();
  55.  
  56. //LoggerFunctor& _functor;
  57. ostringstream _buffer;
  58. uint8_t _indent;
  59. };
  60.  
  61.  
  62. }
  63.  
  64. #include "LogBuffer.cpp"
  65.  
  66. #endif

  1. /**
  2.  * Assumed implementation file of LogBuffer
  3.  */
  4. #ifdef LOGBUFFER_H
  5.  
  6. using namespace Log;
  7.  
  8. LogBuffer::LogBuffer(LogFactor& logFactor){}
  9.  
  10. LogBuffer::~LogBuffer(){}
  11.  
  12. template <class T>
  13. LogBuffer& LogBuffer::operator<<(T & data){
  14.  
  15. ::trace(*this, data); // trace fuction called here
  16. return *this;
  17. }
  18.  
  19. template <class T>
  20. void trace(LogBuffer& msgBuffer, T& data){
  21.  
  22. data.trace(msgBuffer);
  23. }
  24.  
  25. #endif

  1. /**
  2.  * Driver program for testing--
  3.  */
  4. #include <iostream>
  5. #include "LogBuffer.h"
  6.  
  7. using std::cout;
  8. using std::cin;
  9. using std::endl;
  10.  
  11. class Tracer{
  12. public:
  13. Tracer(){}
  14. void trace(LogBuffer& msgBuffer){
  15. cout << "Trace successful" << endl;
  16. }
  17. };
  18.  
  19. class NonTracer{
  20.  
  21. public:
  22. NonTracer(){}
  23. char trace;
  24. };
  25.  
  26.  
  27. int main(){
  28.  
  29. char refChar = '\0'; // dummy variable
  30. Tracer myTracer; // object of type Tracer, has the method trace
  31. NonTracer myNonTracer; // object of type NonTracer, doesn't have trace function but a trace mbmer
  32. Tracer myOtherTracer(); // pointer to a function that accepts no arguments and returns a Tracer
  33. LogBuffer lb (refChar); // making a LogBuffer object and passing it the dummy variable
  34.  
  35. lb << myTracer; // works
  36. // lb << myNonTracer; // obviously doesn't work, but doesn't reproduce desired error
  37. // lb << myOtherTracer; Error 1 error C2228: left of '.trace' must have class/struct/union h:\visual studio 2008\projects\testingtemplates__\testingtemplates__\tesitngtemplate__t.cpp 35 TestingTemplates__
  38. // myOtherTracer.trace(LogBuffer(refChar)); Error 1 error C2228: left of '.trace' must have class/struct/union h:\visual studio 2008\projects\testingtemplates__\testingtemplates__\tesitngtemplate__t.cpp 35 TestingTemplates__
  39.  
  40. cin.ignore();
  41. cin.get();
  42. return 0;
  43. }

Perhaps the errors differ from compiler to compiler, or it may be possible that the examples provided above were not adjacent to the example in the link?

The error seems to occur in gcc (and/or g++?) type compilers so I think the error stated above may be the same thing though I can't confirm it without experience with those compilers.
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 3
Reputation: sagar_d is an unknown quantity at this point 
Solved Threads: 0
sagar_d sagar_d is offline Offline
Newbie Poster

Re: hi

 
0
  #3
Nov 11th, 2008
this is my mini project of testing the code at different compilers I am a learner of testing. My master starts with this task. but he also struck with this point.

Now I clearly explain the scenario.

compiling fib_msg.cpp . It is including header files like fib_msg.h, hf_logger.h, hf_looger_impl.h and hf_list.h . I have taken preprocessor output for fib_msg.cpp. I found that all the files r included one after another.
step 1. In fib_msg.h
#include "hf_logger.h"
#include "hf_list.h
inline
void trace(HF_OLogBuffer& msgBuffer, fib_msg_reqHeader_t& data) 
{
    msgBuffer << "cbHandle=0x";
    msgBuffer << hex << setw(8) << setfill('0') << data.cbHandle << endl; // error : instantiated from here 
    msgBuffer << "cbCorrelator=0x";
    msgBuffer << hex << setw(8) << setfill('0') << data.cbCorrelator << endl; 
    msgBuffer << "errorReporting=";
    msgBuffer << fib_trace_value(g_fib_trace_errorReportingTypes,
                                 data.errorReporting,
                                 "unknown type");
    msgBuffer << endl;
    msgBuffer << "msgSubId=" << data.msgSubId << endl;          
}
step 2. first is the hf_logger.h where u can see the function call on a definition of overloading operator function.

class LogBuffer
{
public:

    LogBuffer(LoggerFunctor& loggerFunctor);
    ~LogBuffer();
    uint8_t*     GetStart(); 
    size_t       GetProcessedSize();
    void        Flush();
    void        SetFormat(ios::fmtflags flags, ios::fmtflags mask); 
    uint8_t     GetIndent();
    void        SetIndent(uint8_t indent);
   // Basic types
    LogBuffer& operator<<(int8_t&   data);       // a character, not a number
    LogBuffer& operator<<(const int8_t&   data); // a character, not a number
    LogBuffer& operator<<(uint8_t&  data);       // a character, not a number
    LogBuffer& operator<<(const uint8_t&  data); // a character, not a number
        // C strings
    LogBuffer& operator<<(const char* data);
    LogBuffer& operator<<(char data[]);      
    // std::string
    LogBuffer& operator<<(std::string& data);
    LogBuffer& operator<<(const std::string& data);
    
    // Generic flat type this function is current issue generator  
    template <class T>
    LogBuffer& operator<<(T& data);
    
    // Single element pointer
    template <class T>
    LogBuffer& operator<<(T* & data);
    // Array
    template <class T>
    LogBuffer& operator<<(const MsgBufferArray<T>& data); 
    // Manipulators
    LogBuffer& operator<<(ios& (*fct)(ios& iosArg));
};
template <class T>
void trace(HF_OLogBuffer& msgBuffer, T& data)  
{
    data.trace(msgBuffer);
}// this is the function call from which we got an error i.e. {request for member 'trace' in 'data', which is of non-class type 'std::ios_base& ()(std::ios_base&)'}

inline
void trace(HF_OLogBuffer& msgBuffer, HF_int8_t& data) 
{
    msgBuffer << data;
}//and so on trace functions definitions..

step 3. then we have hf_logger_impl.h
template <class T>
inline
HF_OLogBuffer& HF_OLogBuffer::operator<<(T& data)
{
    trace(*this, data);//  error: instantiated from 'HF_OLogBuffer& HF_OLogBuffer::operator<<(T&) [with T = std::ios_base& ()(std::ios_base&)]'
    return *this;
}

step 4. Finally with hf_list.h
#include "hf_logger.h"

template <class T, class Alloc=BufferChunkAllocator>
class MsgBufferList
{
public:
    MsgBufferList(Alloc& alloc) {init(alloc);} 
    void init(Alloc& alloc)
    {
        _n         = 0;
        _first     = 0;
        _last      = 0;
        _allocator = &alloc;
    }
    uint32_t size() {return _n;}
       
        
    void trace(HF_OLogBuffer& msgBuffer)
    {
        MsgBufferListElem<T>* elemP = _first;

        for (NPF_uint32_t i = 0; (i < _n) && elemP; i++)
        {
            msgBuffer << elemP;
            elemP = elemP->_next;
        }
    }

    uint32_t              _n;
    MsgBufferListElem<T>* _first;
    MsgBufferListElem<T>* _last;
};

// So now U can understand.
Last edited by sagar_d; Nov 11th, 2008 at 2:29 am.
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 973
Reputation: Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough 
Solved Threads: 107
Alex Edwards's Avatar
Alex Edwards Alex Edwards is offline Offline
Posting Shark

Re: hi

 
0
  #4
Nov 11th, 2008
I think the problem may exist in your hf_logger.h file--

  1. class LogBuffer
  2. {
  3. public:
  4.  
  5. LogBuffer(LoggerFunctor& loggerFunctor);
  6. ~LogBuffer();
  7. uint8_t* GetStart();
  8. size_t GetProcessedSize();
  9. void Flush();
  10. void SetFormat(ios::fmtflags flags, ios::fmtflags mask);
  11. uint8_t GetIndent();
  12. void SetIndent(uint8_t indent);
  13. // Basic types
  14. LogBuffer& operator<<(int8_t& data); // a character, not a number
  15. LogBuffer& operator<<(const int8_t& data); // a character, not a number
  16. LogBuffer& operator<<(uint8_t& data); // a character, not a number
  17. LogBuffer& operator<<(const uint8_t& data); // a character, not a number
  18. // C strings
  19. LogBuffer& operator<<(const char* data);
  20. LogBuffer& operator<<(char data[]);
  21. // std::string
  22. LogBuffer& operator<<(std::string& data);
  23. LogBuffer& operator<<(const std::string& data);
  24.  
  25. // Generic flat type this function is current issue generator
  26. template <class T>
  27. LogBuffer& operator<<(T& data);
  28.  
  29. // Single element pointer
  30. template <class T>
  31. LogBuffer& operator<<(T* & data);
  32. // Array
  33. template <class T>
  34. LogBuffer& operator<<(const MsgBufferArray<T>& data);
  35. // Manipulators
  36.  
  37. // Takes a pointer to an ios that accepts an ios arg, ios_base
  38. LogBuffer& operator<<(ios& (*fct)(ios& iosArg));
  39. };
  40. template <class T>
  41. void trace(HF_OLogBuffer& msgBuffer, T& data)
  42. {
  43. data.trace(msgBuffer);
  44. }// this is the function call from which we got an error i.e. {request for member 'trace' in 'data', which is of non-class type 'std::ios_base& ()(std::ios_base&)'}
  45.  
  46. inline
  47. void trace(HF_OLogBuffer& msgBuffer, HF_int8_t& data)
  48. {
  49. msgBuffer << data;
  50. }//and so on trace functions definitions..

Because you only have a 'specialization' for an ios type (and anything derived from it) and not its super type, you're generalized function is invoked instead of the one you most likely intended to be invoked.

That's my assumption, given the error generated. I only know so much about call-backs, but if what I'm thinking is true your member in fib_msg_reqHeader_t cbHandle is a pointer to a function that takes an ios_base reference and returns an ios_base reference and since you don't have a specialization for your callback the generic type is being called.

You could probably resolve the error by allowing your overloaded<< definition that takes a pointer to a function that accepts and returns an ios reference to instead allow pointers to a function that accepts and returns an ios_base.
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 3
Reputation: sagar_d is an unknown quantity at this point 
Solved Threads: 0
sagar_d sagar_d is offline Offline
Newbie Poster

Re: hi

 
0
  #5
Nov 11th, 2008
Originally Posted by Alex Edwards View Post
I think the problem may exist in your hf_logger.h file--

  1. class LogBuffer
  2. {
  3. public:
  4.  
  5. LogBuffer(LoggerFunctor& loggerFunctor);
  6. ~LogBuffer();
  7. uint8_t* GetStart();
  8. size_t GetProcessedSize();
  9. void Flush();
  10. void SetFormat(ios::fmtflags flags, ios::fmtflags mask);
  11. uint8_t GetIndent();
  12. void SetIndent(uint8_t indent);
  13. // Basic types
  14. LogBuffer& operator<<(int8_t& data); // a character, not a number
  15. LogBuffer& operator<<(const int8_t& data); // a character, not a number
  16. LogBuffer& operator<<(uint8_t& data); // a character, not a number
  17. LogBuffer& operator<<(const uint8_t& data); // a character, not a number
  18. // C strings
  19. LogBuffer& operator<<(const char* data);
  20. LogBuffer& operator<<(char data[]);
  21. // std::string
  22. LogBuffer& operator<<(std::string& data);
  23. LogBuffer& operator<<(const std::string& data);
  24.  
  25. // Generic flat type this function is current issue generator
  26. template <class T>
  27. LogBuffer& operator<<(T& data);
  28.  
  29. // Single element pointer
  30. template <class T>
  31. LogBuffer& operator<<(T* & data);
  32. // Array
  33. template <class T>
  34. LogBuffer& operator<<(const MsgBufferArray<T>& data);
  35. // Manipulators
  36.  
  37. // Takes a pointer to an ios that accepts an ios arg, ios_base
  38. LogBuffer& operator<<(ios& (*fct)(ios& iosArg));
  39. };
  40. template <class T>
  41. void trace(HF_OLogBuffer& msgBuffer, T& data)
  42. {
  43. data.trace(msgBuffer);
  44. }// this is the function call from which we got an error i.e. {request for member 'trace' in 'data', which is of non-class type 'std::ios_base& ()(std::ios_base&)'}
  45.  
  46. inline
  47. void trace(HF_OLogBuffer& msgBuffer, HF_int8_t& data)
  48. {
  49. msgBuffer << data;
  50. }//and so on trace functions definitions..

Because you only have a 'specialization' for an ios type (and anything derived from it) and not its super type, you're generalized function is invoked instead of the one you most likely intended to be invoked.

That's my assumption, given the error generated. I only know so much about call-backs, but if what I'm thinking is true your member in fib_msg_reqHeader_t cbHandle is a pointer to a function that takes an ios_base reference and returns an ios_base reference and since you don't have a specialization for your callback the generic type is being called.

You could probably resolve the error by allowing your overloaded<< definition that takes a pointer to a function that accepts and returns an ios reference to instead allow pointers to a function that accepts and returns an ios_base.
I am very thankful to ur reply. But I didnt get U. error at some other line but u mentioned another line i.e ios_base. Could u please check it once and please give me the reply.

error: this is the function call from which we got an error i.e. {request for member 'trace' in 'data', which is of non-class type 'std::ios_base& ()(std::ios_base&)'}
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 973
Reputation: Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough 
Solved Threads: 107
Alex Edwards's Avatar
Alex Edwards Alex Edwards is offline Offline
Posting Shark

Re: hi

 
0
  #6
Nov 11th, 2008
What I'm saying is change the operator prototype--

  1.  
  2. // Takes a pointer to an ios that accepts an ios arg, ios_base
  3. LogBuffer& operator<<(ios& (*fct)(ios& iosArg));

-- and definition to --

  1. // Takes a pointer to an ios that accepts an ios arg, ios_base
  2. LogBuffer& operator<<(ios_base& (*fct)(ios_base& iosArg));

--but only if the operations within the operator will allow you to do so. Since ios_base is a super-type of ios I'm assuming that ios_base wont have the same functionality (or the same amount of members) as ios.

In the event that you do not want to change the definition of your operator for ios-types, change your cbHandle to accept and return a reference to an ios type instead of an ios_base.


  1. /**
  2.  * Possible definition of fib_msg_reqHeader_t before you decide to change it
  3.  */
  4. struct fib_msg_reqHeader_t{
  5. //...
  6.  
  7. ios_base& (*cbHandle)(ios_base&);
  8.  
  9. //...
  10.  
  11. };


  1. /**
  2.  * Possible definition of fib_msg_reqHeader_t after you decide to change it
  3.  */
  4. struct fib_msg_reqHeader_t{
  5. //...
  6.  
  7. ios& (*cbHandle)(ios&);
  8.  
  9. //...
  10.  
  11. };

--again only do this if it wont make any major changes in other portions of code. Consider each option carefully and if you find a solution you can simply add another stream-extraction operator to handle ios_base types.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the C++ Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC