c++ - 显式构造函数仍在进行转换

标签 c++

我有一个(非常)简单的模板化类型,可以让我在从函数返回时返回一个“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/

相关文章:

c++ - ObjC 中 & 的等价物是什么?

c++ - 是否在退出时清理

c++ - 读/写简单 BMP 图像 C++

c++ - 在 C++ 中以编程方式打开文档

C++访问模板中的内部类

python - vec4 多个 mat4,然后在 Python 中将其设为 vec3

c++ - 删除多态对象和内存泄漏

c++ - 使用具有前向声明类型的模板 - 安全吗?

c++ - 如何使用 Protocol Buffer ?

c++ - 使用 cpprestsdk 将字符串转换为 web::json