Reputation: 11
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
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
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
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
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