Does "explicit" keyword disallow array decaying ?

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
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
Thanks @dutch & @JLBorges for your inputs :)
Topic archived. No new replies allowed.