【问题标题】:Stop implicit conversion for C++98 and C++11停止 C++98 和 C++11 的隐式转换
【发布时间】:2017-02-23 12:47:21
【问题描述】:

我有一个带有get() 方法的模板类,它返回模板化的类型。它还有更多内容,但为简单起见,代码如下所示:

Attribute<float> attr(0.0f);
float value = attr.get();

但是,以下内容也将编译:

Attribute<float> attr(0.0f);
int value = attr.get();

我想让编译器捕捉到它,并告诉我我有一个非法转换。一个简单的方法是创建一个新的Holder&lt;T&gt; 类,它有一个转换运算符到它模板化的类型。 get 方法的工作原理如下:

template<typename T>
Holder<T> Attribute::get()
{
    return Holder<T>(m_value);
}

Holder 类看起来像:

template<typename T>
class Holder 
{
    private:
        T m_value;
    public:
        Holder(T value) : m_value(value) {}
        //implicit conversion
        operator T() const { return m_value; }
};

(我只是在编辑器中写了这个,还没有测试过,但这应该可以在 C++98 中做我想要的)

Attribute<float> attr(0.0f);
// This should now not compile because we have no conversion from
// Holder<float> to int.
int value = attr.get();

当我们迁移到 C++11 时,棘手的一点是,我可能想使用 auto,但突然间,当我这样做时:

Attribute<float> attr(0.0f);
auto value = attr.get();

value 现在将是我不想要的Holder&lt;float&gt; 类型。谁能想到一种让两者都起作用的方法,也许有一些提升魔法。

【问题讨论】:

  • “隐式转换”似乎是矛盾的。
  • value 的类型为Holder&lt;float&gt; 真的有问题吗?必要时不会自动转成float吗?
  • 您可能需要 gcc/clang 标志 -Wconversion
  • 另外,你最好测试一下返回Holder&lt;float&gt;实际上会阻止转换为int。我无法为以下行生成编译错误:int value = attr.get();
  • @Jarod42 是的......这可能是最简单的方法,我只需要检查我没有在其他地方使用隐式转换。我只是想知道是否有人能想到一种“代码中”的方式。

标签: c++ c++11 boost typetraits c++98


【解决方案1】:

您可以在Attribute 类中定义typedef,如下所示:

typedef T value_type;

然后在作业部分:

Attribute<float> attr(0.0f);
decltype(attr)::value_type value = attr.get();

这样你就不需要那个支架了。

如果您坚持使用该持有人,您也可以这样做并从持有人中提取value_type

【讨论】:

  • @Jarod42 是的,但我的解决方案消除了所有隐式转换
  • auto 没有转化。并且您将使用 Attribute&lt;float&gt; attr(0.0f), Attribute&lt;int&gt; attr2(42); decltype(attr2)::value_type = attr.get(); 的错字情况进行隐式转换。它不是更安全,只是更冗长,并且不能解决 C++03 的情况(因为 autodecltype 仅适用于 C++11 及更高版本)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多