关于c ++:可以以某种方式在类定义之外提供运算符bool cast的等价物吗?

Can the equivalent of an operator bool cast be provided outside of a class definition somehow?

我有一些模板化的C++ 03代码,其中包含一个片段,我想编写这样的代码:

1
2
3
4
5
6
template <typeName optType>
std::string
example(optType &origVal)
{
  return bool(origVal) ?"enabled" :"disabled";
}

但是,没有为struct linger定义optType::operator bool(),我不能添加,因为struct不是我的。因此,现在我写的是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <typename optType>
bool
castBool(const optType &value)
{
  return bool(value);
}

template <>
bool
castBool<struct linger>(const struct linger &value)
{
  return bool(value.l_onoff);
}

template <typeName optType>
std::string
example(optType &origVal)
{
  return castBool(origVal) ?"enabled" :"disabled";
}

但是,我想知道是否有一种更简洁的方法来做到这一点?例如,我可以在类外部定义一个静态operator==(),如:

1
2
3
4
5
bool
operator==(const struct linger &lhs, const struct linger &rhs)
{
  return lhs.l_onoff == rhs.l_onoff && lhs.l_linger == rhs.l_linger;
}

所以,也许有一些语法可以告诉编译器如何将一个结构(如EDOCX1[1])提升为bool?


您可以在命名空间中提供一些默认版本:

1
2
3
4
5
6
7
8
9
10
namespace detail {
    template <typename T>
    bool to_bool(const T& val) { return static_cast<bool>(val); }
}

template <typename T>
bool conv_bool(const T& val) {
    using namespace detail;
    return to_bool(val);
}

然后,借助ADL的魔力,您可以在所需类的名称空间中提供to_bool的版本:

1
2
3
4
5
6
7
namespace whatever {
    struct linger { ... };

    bool to_bool(const linger& value) {
        return value.l_onoff;
    }
}

然后到处使用conv_bool

1
2
3
4
5
6
template <typeName optType>
std::string
example(optType &origVal)
{
  return conv_bool(origVal) ?"enabled" :"disabled";
}

如果您提供自己的to_bool()功能,这将是首选。否则,将调用默认值,该值将尝试执行operator bool或其他等效操作。不必处理模板问题。


由于operator bool只能是一个方法,不能是一个独立的函数,所以我认为其中一个解决方案正在从您要强制转换到bool的方法生成派生类,并且只在那里实现您的运算符。除非我们所说的班级是final,否则这是可行的。

1
2
3
4
5
6
7
class Boolable : public optType{
public:
    using optType::optType;
    operator bool() const{
        //your code her
    }
};