Jan 1, 2019 at 3:35pm UTC
Hi,
I am trying to run the following code but getting error.
error: conversion from ‘const char [6]’ to non-scalar type ‘kapil::string’ requested
test.cpp
1 2 3 4 5 6 7 8
#include "my_string.h"
int main() {
string s1 = "hello" ; //fails to compile [1]
string s2{"world" }; //compiles successfully [2]
return 0;
}
The code doesn't give error if "explicit" keyword is removed in constructor string::string(const char*).
I am not able to understand why [2] compiles successfully but [1] fails with explicit keyword ?
Which constructor does [1] call, same constructor as [2] or copy constructor?
mystring.h (partial code)
1 2 3 4 5 6 7 8 9 10 11 12 13
namespace kapil {
class string final {
private :
static constexpr size_t default_capacity_ = 16;
size_t current_capacity_;
size_t sz_;
std::unique_ptr<char []> ptr_;
public :
string();
explicit string(const char *);
string& operator = (const char *);
};
}
my_string.cpp (partial code)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
string::string()
: current_capacity_{ default_capacity_ } {
sz_ = 0;
ptr_ = std::make_unique<char []>(current_capacity_ + 1);
ptr_.get()[0] = '\0' ;
}
string::string(const char * c_string) {
sz_ = std::strlen(c_string);
current_capacity_ = get_appropriate_capacity(sz_);
ptr_ = std::make_unique<char []>(current_capacity_ + 1);
std::strcpy(ptr_.get(), c_string);
}
string& string::operator = (const char * c_string) {
sz_ = std::strlen(c_string);
auto appropriate_capacity = get_appropriate_capacity(sz_);
if (current_capacity_ != appropriate_capacity) {
current_capacity_ = appropriate_capacity;
ptr_ = std::make_unique<char []>(current_capacity_ + 1);
}
std::strcpy(ptr_.get(), c_string);
return *this ;
}
size_t get_appropriate_capacity(size_t new_string_length) {
size_t appropriate_capacity = 16;
if ((static_cast <unsigned long >(new_string_length) << 1) > std::numeric_limits<size_t>::max()) {
appropriate_capacity = new_string_length;
} else {
appropriate_capacity = 16;
if (appropriate_capacity <= new_string_length) {
if (!(new_string_length & (new_string_length - 1))) {
appropriate_capacity = new_string_length << 1;
} else {
while (appropriate_capacity < new_string_length) {
appropriate_capacity <<= 1;
}
}
}
}
return appropriate_capacity;
}
Thanks for any help :)
P.S. : Please check this for complete code :
https://github.com/singhkapil2905/cplusplus-string-implementation
Last edited on Jan 1, 2019 at 4:01pm UTC
Jan 1, 2019 at 3:56pm UTC
It has nothing to do with "array decay".
string s1 = "hello"; is not calling operator= at all. It's a form of copy initialization and therefore requires the constructor. You either need to make it non-explicit (like std::string) or explicitly say string s1 = string("hello");
https://en.cppreference.com/w/cpp/language/copy_initialization
Last edited on Jan 1, 2019 at 3:58pm UTC
Jan 1, 2019 at 4:38pm UTC
Thanks @dutch & @JLBorges for your inputs :)