【问题标题】:C++ cannot convert 'const char*' to 'std::string*'C++ 无法将 'const char*' 转换为 'std::string*'
【发布时间】:2011-05-13 13:55:02
【问题描述】:

我在下面有这段代码,编译时出现错误:

error: cannot convert 'const char*' to 'std::string*' for argument '1' to 'void sillyFunction(std::string*, int)'

#include <iostream>
#include <string>

using namespace std;
int counter = 0;

void sillyFunction(string * str, int cool=0);

int main(){
    sillyFunction("Cool");
    sillyFunction("Cooler", 1);
    return 0;
}

void sillyFunction(string * str, int cool){
    counter++;
    if (cool){
        for (int i=0; i<counter; i++) cout << *str << endl;
    } else {
        cout << *str << endl;
    }
}

【问题讨论】:

    标签: c++ string stl


    【解决方案1】:

    不要将您的参数作为string * 尝试使用const string &amp; 代替

    编辑:

    std::stringconst char* 是不同的类型。 std::string 已经有从字符串文字(例如:"Cool")到实际字符串对象的转换。因此,通过传入字符串文字 "Cool",您在某种意义上是传入了 std::string 对象,而不是指向对象的指针。

    我选择使用const string &amp; 的原因主要是出于个人编码实践。这最大限度地减少了堆栈内存的使用,并且由于您传递的是常量字符串文字,因此无需修改参数。

    如果您从 string * 更改,也不要忘记您不再需要在您的 cout 中取消引用它:

    if (cool){
        for (int i=0; i<counter; i++) cout << str << endl;
    } else {
        cout << str << endl;
    }
    

    【讨论】:

    • 如果你详细说明你的答案并解释他为什么要这样做,我会支持你的答案。
    【解决方案2】:

    改变

    void sillyFunction(string * str, int cool){
       counter++;
        if (cool){
            for (int i=0; i<counter; i++) cout << *str << endl;
        } else {
            cout << *str << endl;
        }
    }
    

    void sillyFunction(const char* str, int cool){
        counter++;
        if (cool){
            for (int i=0; i<counter; i++) cout << str << endl;
        } else {
            cout << str << endl;
        }
    }
    

    【讨论】:

      【解决方案3】:

      解释问题究竟是什么...

      虽然编译器很乐意通过适当的std::string 构造函数将char */C 字符串“转换”为std::string,但这不是您所要求的。

      您已要求 指针 指向 现有 std::string 对象。根据定义,传递给函数的必须是已经存在std::string(或后代)对象的地址。

      您必须将指针理解为一种独特的类型——您的函数采用pointer-to-std::string“对象”。虽然可以通过指向std::string 的指针访问std::string,但指针本身不是 std::string,也不能“转换”为std::string,也不能被视为指向字符的指针(反之亦然)。

      最简单的替代方案确实是对 std::string (const std::string &amp;) 的 const 引用。 const,在这种情况下,因为你没有做任何事情来修改字符串。如果是,那将是另一回事,您必须仔细考虑是否打算让调用者看到您的更改。

      通过这样做,你是说你想要一个 std::string 对象(请记住,对对象的引用就是那个对象,特别是参见 C++ FAQ 8.5),它允许编译器当使用 char * 调用函数时,调用适当的构造函数为您创建一个 std::string(无论是否为 const)。

      同时,如果有人将实际 std::string 传递给您,构造函数将被避免,并且您获得的效率与您使用pointer-to-std::string 相同。双赢。

      当然,您也可以选择简单的std::string,但在这种情况下,您总是会获得传入字符串的副本,无论是 C 字符串还是 @ 987654339@。有时这是可取的,有时则不是。在您的情况下,您除了打印字符串外什么都不做,从而使开销变得不必要。

      【讨论】:

        【解决方案4】:

        您可以从const char * 转换为string,但不能转换为string *

        也许您希望您的 sillyFunction 获取 const 引用?

        void sillyFunction(const string &str, int cool){
            counter++;
            if (cool){
                for (int i=0; i<counter; i++) cout << str << endl;
            } else {
                cout << str << endl;
            }
        }
        

        【讨论】:

          【解决方案5】:

          应该是

          void sillyFunction(const string& str, int cool=0);
          

          【讨论】:

            【解决方案6】:

            如果你要为你的函数使用指针,你必须在某处声明字符串。需要分配内存。所以要么声明一个变量,要么调用 new 来为字符串创建内存。

            int main(){
                string str = "Cool";
                string str2 = "Cooler";
                sillyFunction(&str);
                sillyFunction(&str2, 1);
                return 0;
            }
            

            【讨论】:

              【解决方案7】:

              您可以通过将原型更改为:

              void sillyFunction(string const &str, int cool=0);
              

              char const * 可以隐式转换为临时的std::string,而后者又可以通过引用传递 (std::string const &amp;)。没有隐式转换为指针 (std::string *),这就是您收到错误的原因。

              【讨论】:

              • 不应该是const string &amp;str吗?
              • @ultimatebuster,是一样的。怎么写只是个人喜好问题。
              【解决方案8】:

              我有一个非常简单的解决方案,使用字符串复制

              字符[20] strcpy(s,const char *p);

              那么你有 *p 指向的字符串在 s... 它有效..

              【讨论】:

                猜你喜欢
                • 2014-07-13
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-10-28
                相关资源
                最近更新 更多