Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error: conversion from 'const char [5]' to non-scalar type in c++

Tags:

c++

string

public:
    string str;

    Test(string& str){
        this->str=str;
        cout<<"constructor"<<endl;
    }
 

};

int main() {
    Test t="test";
    return 0;
}

In this code I get the error "..\src\Test.cpp:30:9: error: conversion from 'const char [5]' to non-scalar type 'Test' requested "?

Why is then the following code ok?

#include <iostream>
using namespace std;

class Test{

public:
    string str;

    Test(string str){
        this->str=str;
        cout<<"constructor"<<endl;
    }

    Test(const Test &test){
        cout<<"copy constructor"<<endl;
        this->str=test.str;
    }

};

int main() {
    Test t=Test("test");
    return 0;
}
like image 837
jiafu Avatar asked Oct 24 '25 06:10

jiafu


2 Answers

Test t="test";

This tries to:

  • Convert the string literal (which is an array of characters, char[5]) into a temporary string
  • Convert the temporary string to Test

This fails for two reasons:

  • An implicit conversion sequence can't involve more than one user-defined conversion. Two are needed here.
  • A temporary can't bind to a non-const lvalue reference, which is what your conversion constructor Test(string&) wants.

Your second example fixes these problems by:

  • Making the conversion from string to Test explicit, Test(...). Now there is only one implicit conversion, from char[5] to string. Note that this is rather a verbose way to initialise it; Test t("test") would do the same thing.
  • Declaring the conversion constructor to take string by value, not reference. A const reference, const string&, would also work, as would a const char*.

Both of these changes are necessary, since each fixes just one of the two problems.

like image 188
Mike Seymour Avatar answered Oct 26 '25 19:10

Mike Seymour


You are only allowed one implicit conversion between user defined types. Your code has an implicit conversion from const char[6] (which decays to const char*) to std::string, and from std::string to Test. This is the reason changing the signature to Test(const std::string&) will not work.

Try changing the constructor signature to

#include <string>

struct Test
{
  Test(const char* c) : s_(c) {}
  std::string s_;
};

int main()
{
  Test t = "Hello";
}
like image 20
juanchopanza Avatar answered Oct 26 '25 20:10

juanchopanza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!