重载到bool运算符的非成员转换

overloading non-member conversion to bool operator

本文关键字:成员 转换 运算符 bool 重载      更新时间:2023-10-16

我正在尝试为std::bitset 编写布尔转换运算符

我试过了:

template<size_t size>
operator bool(std::bitset<size> & b)
{
    return b.any();
}

但我有

error C2801: 'mynamespace::operator bool' must be a non-static member

从我的视觉工作室。

但当我查阅C2801的解释时,它没有提到转换运算符(只提到=,->,[],())

那么,是否有可能以某种方式编写"转换std::bitset为布尔运算符?"

(我不能在if语句中调用b.any(),因为当std::bitset被无符号或其他替换时,必须运行相同的代码

typedef std::bitset<x> Bitset;
//typedef unsigned Bitset;

所以理想的语法是:

Bitset b = whatewer;
if(b)
    doStuff();

)

如果这种过载是不可能的,建议的解决方法是什么?

到目前为止,我使用它的方式是:

if(b == Bitset(0))
    doStuff(); 

但我不喜欢。

感谢

正如错误消息所说,转换运算符必须是类的非静态成员。这是真的。

我不能在if语句中调用b.any(),因为当std::bitset被无符号或其他东西替换时,必须运行相同的代码。

如果这是您的问题,那么您可以使用函数重载,并通过参数调用它,该参数将返回布尔值:

template<typename T>
bool to_bool(T const & b)
{
    return b; //implicit conversion (if allowed) for all other types
}
template<size_t N>
bool to_bool(std::bitset<N> const & b)
{
    return b.any();
}

然后将其用作:

if (to_bool(whatever)) 
{
}

它将调用正确的过载。如果whatever的类型是std::bitset<N>,则将调用第二个重载函数,否则将调用第一个重载函数。

§12.3.2/1:"名称为[…]的类X的成员函数指定从X到指定类型的转换…"(C++11使用相同的节号和几乎相同的措辞,只是添加了该函数不带参数)。

定义转换的另一种可能方式是构造函数(§12.3.1),它显然也是类成员。

简而言之,是的,转换必须始终定义为成员函数。

做你想做的事情的一种方法是围绕std::bitset编写一个包装器,提供你关心的转换:

template <int size>
class mybitest {
    std::bitset<size> bits;
public:
    operator bool() { return bits.any(); }
}

但是,如果您决定这样做,您将需要为您正在使用的bitset的所有部分(actors、assignment等)编写转发函数

标准对此有点不清楚(12.3.2):

类X的成员函数不具有形式为[…]的参数,指定从X到conversion-type-id指定的类型的转换。这种函数称为转换函数。无法指定返回类型如果转换函数是成员函数,则转换函数的类型(8.3.5)为"不带参数的函数返回转换类型id"。

第一句话似乎暗示只有成员函数可以是转换函数,但我不确定条件"如果转换函数是成员函数"的目的是什么。

我认为第一句话具有约束力,并得出结论,转换函数必须是成员函数。

如果这对某人有帮助,您实际上可以提供一个非运算符,而不是

template<size_t size>
operator !(std::bitset<size> & b)
{
    return !b.any();
}

并使用!!习语:

if (!!whatever)
{
}

仍然不理想,但我认为有点接近。