【问题标题】:C++ << operator overloading and templates with ArduinoArduino的C++ <<运算符重载和模板
【发布时间】:2013-06-14 12:41:43
【问题描述】:

我正在开发一个 arduino 项目,我一直在使用以下模板通过 打印各种数据类型

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

在尝试处理使用 Arduinos P 宏存储的 char 数组之前一直很好,该宏将数据存储在闪存而不是 ram 中

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

导致编译错误

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

虽然以下编译

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

我试图创建一个

 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; }

虽然我仍然遇到同样的编译器错误。

WebServer::printP 的声明是

 void printP(const prog_uchar *str);

非常感谢任何反馈和帮助!

完整的编译器错误:

 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

另外定义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);
 }

【问题讨论】:

  • 真的是server.printP(CT_PLAIN); 还是你的意思是server.print(P(CT_PLAIN));?第一种情况,P(CT_PLAIN)的类型是什么,printP的签名是什么?
  • 是的,我仔细检查了它的server.printP(CT_PLAIN); CT_PLAIN is static const prog_uchar CT_PLAIN[12] = "text/plain\n"printP方法是void WebServer::printP(const prog_uchar *str)
  • PrintWebServer是什么关系?
  • WebServer类减速class WebServer: public Print

标签: c++ templates operator-overloading arduino


【解决方案1】:

问题是在您的第一个示例中,您正在调用 printP(const prog_uchar*) 并使用 const prog_uchar[12] 类型的参数,该参数可以轻松转换为 const prog_uchar*

当您使用operator&lt;&lt; 时,您使用const prog_uchar[12] 类型的对象调用函数print(),但您没有任何适合此类型的print 重载。因此,编译器会寻找不同的print 重载并采用最合适的。但是,在您的情况下,不仅有一个“最合适”的重载,而是其中的 8 个,因此您最终会收到详细的错误消息。

解决您的问题的方法是将您要打印的内容显式转换为const char*

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

另一种解决方案是为print 提供const prog_uchar* 的重载。

【讨论】:

  • 感谢 Morwenn 的详细回复,现在很有意义,感谢出色的解释!
  • 我想我明白了,虽然这个解决方案因为 P 宏而不起作用。看看 WebServer::printP 是如何运作的,我相信它使用单个字符并在处理器闪存中查找它们,这样的类型转换只会返回一个闪存点的 char 数组。抱歉我的解释不好,我正在学习这个。我添加了 WebServer::printP 的定义,这可能比我上面写的解释得更好
  • @TimKalinowski 如果你同时没有找到解决方案,我稍后会尝试看看,我现在很忙,对不起^^"
  • 没问题,我非常感谢您已经投入的时间!
【解决方案2】:
 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; }

重载没有返回类型,为了解决模板中的歧义,将其更改为子类

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    相关资源
    最近更新 更多