Явные конвертирующие конструкторы

Рекомендуется использовать explicit для конвертирующих конструкторов (с одним аргументом) и конвертирующих операторов во избежание неявных преобразований.

Неправильно:

class MyString {
public:
    MyString(size_t n) {
        buff = std::make_unique<char[]>(n);
    }
private:
    std::unique_ptr<char[]> buff;
};

int main() {
    MyString name = 'a'; // Неявное преобразование к int
    return 0;
}

Правильно:

class MyString {
public:
    explicit MyString(size_t n);
private:
    std::unique_ptr<char[]> buff;
};

int main() {
    MyString name = 'a'; // Ошибка компиляции
    return 0;
}

То же самое следует применять к конвертирующим операторам.

Неправильно:

class MyString {
public:
    explicit MyString(size_t n) {
        buff = std::make_unique<char[]>(n);
    }
    operator int() const { return 42; }
private:
    std::unique_ptr<char[]> buff;
};

int main() {
    MyString name(10);

    int value = name; // Нежелательное неявное преобразование

    return 0;
}

Правильно:

class MyString {
public:
    explicit MyString(size_t n) {
        buff = std::make_unique<char[]>(n);
    }
    explicit operator int() const { return 42; }
private:
    std::unique_ptr<char[]> buff;
};

int main() {
    MyString name(10);

    int value = static_cast<int>(name); // Ok

    return 0;
}