Deilor
Deilor

Reputation: 11

Conversion from const char[] to class with constructor from string

I try to pass a string to a function instead an object of class A, but I get an error. Why is it not working and how can I make it work?

#include <string>

class A {
public:
    A(const std::string &str) {

    }
};

void test(const A &a) {

}

int main()
{
    A a("abc"); //it's ok
    test(a); //it's ok
    test("abc"); //error?
    return 0;
}

I don't want to pass a string object to test like test(std::string("abc")). I need convert it from const char*

Upvotes: -1

Views: 766

Answers (4)

InTheWonderlandZoo
InTheWonderlandZoo

Reputation: 183

Import string literal declaration like this or equivalent:

using namespace std::string_literals;
// or
using std::string_literals::operator""s;

(See Using string literals without using namespace std).

Then you can use c++ std::string literal "abc"s like this.

test("abc"s);

Upvotes: 0

Serge Ballesta
Serge Ballesta

Reputation: 148965

The problem is that the standard only allow direct implicit conversions.

The following conversions are defined: const char* -> std::string and const std::string -> A

That means that you can safely pass a const std::string where a A is expected, but not an implicitly convertible to std::string object. Transitivity does not work here.

So you will have to do:

test(std::string("abc"));    // ok...

Upvotes: 0

Robert Andrzejuk
Robert Andrzejuk

Reputation: 5222

The problem is with the conversions. "There can be only one" user defined conversion.

Here is :

 const char * -> std::string -> A

So you need to remove a conversion. A way to fix it is to add the suffix 's' at the the end of the string :

test("ABC"s);

https://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s

Another way is to add the function :

void test(const std::string& s)
{
    test(A(s)) ;
} 

Upvotes: 0

NathanOliver
NathanOliver

Reputation: 180650

In the implicit conversion sequence of one type to another, there is a rule that states: At most, only one user defined conversion can be applied. In

test("abc");

You need two user defined conversions. First you need to conversion from const char[N] to std::string, which is considered a user defined conversion1. Then you need to convert that std::string to a A, which would be a second user defined conversion. That is the reason you get the error


To fix, you can use

test(A("abc"));
//or
test(std::string("abc"));

and now you have one explicit user defined conversion, and one implicit conversion, satisfying the one implicit conversion rule.

You could also provide a constructor for A that accepts a const char* so that you can directly convert from "abc" to an A.


1: Even though std::string is part of the standard library, it is not a "built in" type, but a library type. This means it is counted as a user defined type, even though it shipped with your implementation.

Upvotes: 2

Related Questions