我有一个(非常)简单的模板化类型,可以让我在从函数返回时返回一个“IsValid”标志。它是这样的:
template <typename T>
struct Validated
{
private:
T m_value;
bool m_isValid;
public:
Validated() : m_value(), m_isValid(false) {}
explicit Validated(T const& value) : m_value(value), m_isValid(true) {}
explicit Validated(bool isValid, T const& value) : m_value(value), m_isValid(isValid) {}
explicit Validated(bool isValid, T&& value) : m_value(value), m_isValid(isValid) {}
bool IsValid() const { return m_isValid; }
T const& Value() const { return m_value; }
};
也许我对 explicit
说明符有些不理解,但我想知道为什么下面的工作正常,我怎样才能避免从 bool 到 double 的转换?
void someFunc()
{
Validated<double> foo(1.0); // this makes perfect sense
Validated<double> bar(true); // works... (sets m_value to 1.0)
}
一直在查看类似的问题/答案,但找不到令人满意的答案。我知道 std::optional
存在,但我们还没有进入 c++17。在 VS2012/v110 上试过这个。
更新:如建议的那样,删除 bool 的构造函数即可完成工作(从 c++14 开始)。它不适用于 c++11 (VS2012/toolset v110)。
最佳答案
您可以简单地删除采用单个 bool
的构造函数:
Validated(bool value) = delete;
注意:如果需要,您可能需要一些额外的预防措施 Validated<bool>
成为一个有效的类型。
您还可以阻止除 T
以外的任何类型的构造(比上一个强):
template <class U>
Validated(U) = delete;
这甚至适用于 Validated<bool>
因为施工来自 T
将匹配您的 Validated(T const&)
从 T
以外的任何类型构造时重载将匹配已删除的模板。
此方法会阻止(甚至显式)构造 Validated<double>
来自 1
, 1f
等,因此您可能不想使用它。
explicit
不会使您的代码格式错误,它会阻止 Validated<T>
的隐式构造来自T
,例如:
void f(Validated<double>);
f(1.0); // ill-formed because the conversion would be implicit
关于c++ - 显式构造函数仍在进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51047118/