c ++类型转换运算符重载和隐式转换

时间:2015-02-03 20:13:46

标签: c++ casting overloading

如果我正在重载类型转换操作符,当需要隐式转换并且找不到一个时,我遇到了编译错误。考虑一个简单的例子,我有一个包含类型的包装类(在这种情况下是一个long long):

class my_wrapper
{
    long long state;

public:
    my_wrapper(long long _in) : state(_in) {}

    my_wrapper& operator=(const long long rhs)
    {
        state = rhs;
        return *this;
    }

    operator long long()
    {
        return state;
    }
};

现在的问题是,如果我想将代码转换为其他内容(例如,void * ...假设我在64位上),如果没有指定两个强制转换,则以下内容不起作用:

my_wrapper x1 = my_wrapper(5ll);
void* i1 = (void *) x1; // Compile Error: no suitable conversion function exists
void* i1 = (void *) (long long) x1; // Works

VS。如果我写了类似的东西:

long long i1 = 5ll;
void* i2 = (void *) i1; // Works

没什么大不了的,但只是好奇是否可以指定“operator long long()”如果没有其他转换就应该用作默认值。

2 个答案:

答案 0 :(得分:1)

[over.match.conv] /(1.1):

  

考虑S及其基类的转换函数。   那些未隐藏在S内的非显式转换函数   和yield类型T 或可以通过a转换为T类型的类型   标准转换序列(13.3.3.1.1)是候选函数。

从积分类型到void* 1 没有标准转换序列,因此转换运算符不是候选者。

您可以尝试使用转化运算符模板:

template <typename T>
operator T()
{
    return T(state);
}

1 值为零的整数文字是例外。

答案 1 :(得分:1)

由于(void *)x1有效地为您提供了x1.state的地址 你可以简单地实现一个void *强制转换操作符。

像这样:

operator void *()
{
    return &state;
}

这样做的缺点是您现在可以将my_wrapper转换为void * 隐式

幸运的是,您可以使用explicit说明符在 C ++ 11 中阻止这种情况:

explicit operator void *()
{
    return &state;
}