停止C ++ 98和C ++ 11的隐式转换

时间:2017-02-23 12:47:22

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

我有一个带有get()方法的模板化类,它返回模板化的类型。除此之外还有更多内容,但为了简单起见,代码看起来像:

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

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

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

我希望编译器能够捕获它,并告诉我我有非法转换。一种简单的方法是创建一个新的Holder<T>类,它具有一个转换运算符,该运算符是模板化的类型。 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<float>类型。任何人都可以想到一种允许两种方式工作的方式,也许还有一些提升魔法。

1 个答案:

答案 0 :(得分:0)

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

typedef T value_type;

然后在作业部分:

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

这样你就不会需要那个持有人。

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