Issue with making single argument constructor as explicit

Hi,

As per the cpp guidelines mentioned in : https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-explicit
the single argument constructors should be made explicit.

But I am facing the following issue following the above mentioned guideline


my_string.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace mynamespace {
  class string final {
    private:
      char* ptr_;
      size_t sz_;
    public:
      string() noexcept;
      explicit string(const string&);
      explicit string(string);
      explicit string(string&&) noexcept;
      string& operator = (const string&);
      string& operator = (string&&) noexcept;
      ~string();



      explicit string(const char*);
  };
}


my_string.cpp
1
2
3
4
5
6
7
8
9
10
namespace mynamespace {
  string::string() noexcept : ptr_{nullptr}, sz_{0} {
  }

  string::string(const string& other) {
    sz_ = strlen(other.ptr_);
    ptr_ = new char[sz_ + 1];
    strcpy(ptr_, other.ptr_);
  }
}


test.cpp
1
2
3
4
using namespace mynamespace;
string s3 = string{"brother"}; //[1]
//[1] gives error : no matching function for call to //mynamespace::string::string(mynamespace::string)’
//string s3 = string{"brother"}; 


[a]
I understand that removing "explicit" keyword will make the code work, but I wish to know how to make it work with explicit keyword ?

[b]
I tried defining another constructor :
 
   explicit string(string);

but this gives the error : invalid constructor; you probably meant ‘mynamespace::string (const mynamespace::string&)

Why is this constructor invalid ?

Thanks for any help :)
Last edited on
CppCoreGuidelines wrote:
Note Copy and move constructors should not be made explicit because they do not perform conversions. Explicit copy/move constructors make passing and returning by value difficult.

Explicit is not actually what causes an error in your code (assuming you use C++17 or later). Instead the problem is that mynamespace::string doesn't have a constructor that accepts a string literal.
Last edited on
Hi @Peter87, apologies for not putting the entire list of constructors.

Thanks for the answer.

I am still wondering why [b] is not valid.
Last edited on
explicit string(string);

A class cannot have a single-parameter constructor that takes an object of the same class by value. That is what the copy constructor (string(const string&)) is for.
Last edited on
Topic archived. No new replies allowed.