Вы можете добавить другой конструктор, чтобы отклонить все, что не совсем T
:
template <typename T>
struct M {
M(std::string a, std::string b, T value = T(), const bool ready = false);
template <typename U>
M(std::string, std::string, U, bool = false) = delete;
};
M<int>("hello", hello", true)
предпочтет шаблон конструктора, который будет удален. Но обратите внимание, что так будет и M<int>("hello", "hello", '4')
, а также M<int>("hello", "hello", 4u)
. Так что это вопрос действительно проработки, какие именно вещи вы хотите удалить.
Если вы буквально хотите отклонить только bool
, вы можете сделать это, ограничив шаблон:
template <typename U, std::enable_if_t<std::is_same_v<U, bool>, int> = 0>
M(std::string, std::string, U, bool = false) = delete;
Или в C ++ 20:
template <std::same_as<bool> U>
M(std::string, std::string, U, bool = false) = delete;
или:
M(std::string, std::string, std::same_as<bool> auto, bool = false) = delete;
Если сделать это таким образом, можно будет конструировать M<bool>
из двух string
s и bool
, поскольку конструктор без шаблона все равно будет лучше матч.