![](/img/trans.png)
[英]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.