【问题标题】:Why is it trying to send a char array instead of a string?为什么它试图发送一个 char 数组而不是一个字符串?
【发布时间】:2011-01-19 20:25:03
【问题描述】:

我的函数声明是
siteObject(std::string& url, std::string& get, std::string& post);

那为什么是site("String 1", "String 2", "String 3");创建不匹配类型错误。它说它需要一个字符串引用并且它正在接收一个 char 数组。如果您需要更多详细信息,请在 cmets 中询问。

【问题讨论】:

  • 长话短说:C 设计师制作了字符串文字类型char[]; C++ 设计者使 C++ 与 C 兼容,并给包括你在内的每个 C++ 程序员带来了一大堆烦恼,包括这个。

标签: c++ class function types arrays


【解决方案1】:

因为有一个对std::string 构造函数的隐式调用,它创建了一个临时对象。您不能对临时对象进行非常量引用(因为修改临时对象没有意义)。

因此,要么修改你的函数以采用 const 引用,要么按值,或者将非临时对象传递给它。

【讨论】:

  • 这是唯一的方法吗?
  • 这不适用于比 MSVC 更符合标准的编译器。由于您想将临时对象作为非常量引用传递。
  • @Will03,你也可以把你的程序写成siteObject(const std::string & url , const std::string& get, etc).
  • @Muggen:如果函数中的字符串没有改变,那就行了。
【解决方案2】:

你的siteObject 函数:

siteObject(std::string& url, std::string& get, std::string& post);

对不能绑定到右值(或临时值)的字符串对象进行非常量引用。

当您尝试使用字符串字面量调用函数时,编译器必须将这些参数(char*)转换为与参数类型匹配的参数 - 该转换会生成一个临时的 std::string 对象。

如果您希望能够将它们绑定到临时对象,则需要更改您的函数以接受 const 引用:

siteObject(std::string const& url, std::string const& get, std::string const& post);

或者你可以传递值而不是引用:

siteObject(std::string url, std::string get, std::string post);

【讨论】:

    【解决方案3】:

    您需要让您的函数接受const std::string& str 或构造要传入的字符串实例,而不是依赖于 char* 到字符串对象的隐式转换。

    【讨论】:

      【解决方案4】:

      正确的调用是:

      std::string url("...");
      std::string get("...");
      std::string post("...");
      
      siteObject(url, get, post);
      

      这是有道理的,因为方法签名意味着您可以从三个字符串(非 const 引用)中返回某些内容,并且您可以使用这些返回值。

      如果这不是本意,并且您有能力更改 siteObject() 方法,那么您应该这样做:

      siteObject(std::string const & url, std::string const & get, std::string const & post);
      

      并使用您原来的电话。

      【讨论】:

      • 那不是在回答问题吗??
      • @Will03Uk:更新了答案!
      【解决方案5】:

      以双引号字符输入的字符串来自 C++ 的 C 遗产(它们被称为 C 字符串或 NUL 终止的字符串)。它们由编译器实现为char 的数组。相反,std::string 是一个旨在简化字符串操作的 C++ 类。它拥有一个 C 字符串(并且可以从一个 C 字符串创建,因为它有一个接受 const char* 的构造函数),并管理它的内存。

      既然存在const char* 中的std::string 的构造函数,并且C 字符串与该类型兼容,编译器为什么不能调用该函数?这是因为该函数正在对 std::string 对象进行非常量引用。在这种情况下不能使用构造函数,因为创建的对象将是临时对象,并且您无法获得对临时对象的非常量引用,因为被调用的函数可能会改变它。

      您可以创建std::string 并将它们传递给函数:

      std::string s1("String 1");
      std::string s2("String 2");
      std::string s3("String 3");
      site(s1, s2, s3);
      

      或者您可以更改 site 函数的原型以接受 const 引用。这只有在函数不改变对象并且您可以访问代码时才有可能:

      // Declaration
      void site(const std::string& s1, const std::string& s2, const std::string s3);
      
      // Usage
      site("String 1", "String 2", "String 3");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        • 2011-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多