3

I'm working on an arduino project where I have been using the following template for printing various data types with the << operator

template<class T>
inline Print &operator <<(Print &obj, T arg)
{ obj.print(arg); return obj; }

Which has been fine until trying to process char arrays stored with Arduinos P macro which stores data in flash instead of ram

//params stored in flash using P() from webduino library
P(CT_PLAIN) = "text/plain\n";
server << CT_PLAIN;

Which results in the compiler error

httpServer.h : : In function 'Print& operator<<(Print&, T) [with T = const prog_uchar*]':
httpServer.cpp : instantiated from here
httpServer.h : call of overloaded 'print(const prog_uchar*&)' is ambiguous

Although the following compiles

//params stored in flash using P() from webduino library
P(CT_PLAIN) = "text/plain\n";
server.printP(CT_PLAIN);

I have tried to create a << operator overload but I don't completely understand the syntax and methodology, I have been researching for several hours to no avail and would highly appreciate any feedback.

 WebServer &operator <<(WebServer &server,const prog_uchar *str)
 { server.printP(str); }

 template<class T>
 inline Print &operator <<(Print &obj, T arg)
 { obj.print(arg); return obj; }

Although I still get the same compiler error.

The declaration of WebServer::printP is

 void printP(const prog_uchar *str);

Any feedback and assistance would be highly appreciated!

The complete compiler error:

 Compiling 'webapp' for 'Arduino Mega 2560 or Mega ADK'
 httpServer.h : : In function 'Print& operator<<(Print&, T) [with T = const prog_uchar*]':
 httpServer.cpp : instantiated from here
 httpServer.h : call of overloaded 'print(const prog_uchar*&)' is ambiguous
 Print.h : print(const String&) <near match>
 Print.h : print(const char*) <near match>
 Print.h : print(char) <near match>
 Print.h : print(unsigned char, int) <near match>
 Print.h : print(int, int) <near match>
 Print.h : print(unsigned int, int) <near match>
 Print.h : print(long int, int) <near match>
 Print.h : print(long unsigned int, int) <near match>
 Error compiling

Additionally the definition of WebServer::printP

 void WebServer::printP(const prog_uchar *str)
 {
 // copy data out of program memory into local storage, write out in
 // chunks of 32 bytes to avoid extra short TCP/IP packets
   uint8_t buffer[32];
   size_t bufferEnd = 0;

   while (buffer[bufferEnd++] = pgm_read_byte(str++))
   {
     if (bufferEnd == 32)
     {
       m_client.write(buffer, 32);
       bufferEnd = 0;
     }
   }

   // write out everything left but trailing NUL
   if (bufferEnd > 1)
     m_client.write(buffer, bufferEnd - 1);
 }
4

2 回答 2

5

The thing is in your first example, you are calling printP(const prog_uchar*) with an argument of type const prog_uchar[12] which is trivially convertible to const prog_uchar*.

When you use operator<<, you are calling the function print() with your object of type const prog_uchar[12] but you don't have any print overload suitable for this type. So, the compiler looks for the different print overloads and takes the most suitable. However, there is not only one "most suitable" overload in your case, but 8 of them, hence the detailed error message you have in the end.

A solution to your problem would be to explicitly cast what you are trying to print to const char*:

P(CT_PLAIN) = "text/plain\n";
server << (const char*) CT_PLAIN;

Another solution would be to provide to print an overload for const prog_uchar*.

于 2013-06-14T13:34:30.520 回答
1
 WebServer &operator <<(WebServer &server,const prog_uchar *str)
 { server.printP(str); return server;}

 template<class T>
 inline WebServer &operator <<(WebServer &obj, T arg)
 { obj.print(arg); return obj; }

重载没有返回类型并且为了解决模板中的歧义,它被更改为子类

于 2013-06-16T12:28:29.267 回答