[英]Prevent implicit conversion of QObject* to bool : prevent 'Multiple constructor' warning
[英]How to prevent bool to int conversion in constructor?
我有以下课程,尽可能接近我的生产代码:
#include <iostream>
template <typename T>
struct M {
M(std::string a, std::string b, T value = T(), const bool ready = false) : m_value{value}, m_ready{ ready } {}
T m_value;
bool m_ready;
};
auto main() -> int {
{
M<int> m{"a", "b"};
std::cerr << m.m_value << std::endl;
}
{
M<int> m{"a", "b", true};
std::cerr << m.m_value << std::endl;
}
}
在第一种情况下, m_value
的值如预期的m_value
为 0。 在第二个中它是 1,因为它采用 bool 的值。 有没有办法避免转换?
您可以通过显式删除直接将bool
作为第三个参数的版本来阻止转换:
M(std::string, std::string, bool, bool = false) = delete;
但是,如果T
是bool
,那将导致问题。 因此,您需要使用一些 SFINAE 体操来使此定义仅在T
可转换为bool
但实际上不是bool
。
我认为这有效
#include <iostream>
#include <type_traits>
template <typename T>
struct M {
template <typename U=T, typename=std::enable_if_t<std::is_same_v<T, U>>>
M(std::string a, std::string b, U value = U(), const bool ready = false) : m_value{value}, m_ready{ ready } {}
T m_value;
bool m_ready;
};
auto main() -> int {
{
M<int> m{"a", "b"};
std::cout << m.m_value << std::endl;
}
{
M<int> m{"a", "b", 1};
std::cout << m.m_value << std::endl;
}
{
// This does not compile
// M<int> m{"a", "b", true};
// std::cout << m.m_value << std::endl;
}
{
// This compiles
M<bool> m{"a", "b", true};
std::cout << m.m_value << std::endl;
}
return 0;
}
您可以添加另一个构造函数来拒绝任何不完全是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)
也是如此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
构造,因为非模板构造函数仍然是更好的匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.