3

I have some templated C++-03 code that includes a snippet that I'd like to write something like this:

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

However, there is no optType::operator bool() defined for struct linger and I cannot add one as that struct is not mine. Therefore, for now, I have written it as this instead:

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";
}

But, I'm wondering if there is a more succinct way to do this? For example, I can define a static operator==() outside of a class, such as like this:

bool
operator==(const struct linger &lhs, const struct linger &rhs)
{
  return lhs.l_onoff == rhs.l_onoff && lhs.l_linger == rhs.l_linger;
}

So perhaps there is some syntax to tell the compiler how to promote a struct such as the struct linger here to a bool?

WilliamKF
  • 41,123
  • 68
  • 193
  • 295
  • `operator bool()` can only be implemented as a member, not standalone. Your existing template specialization is the solution. – Remy Lebeau Jul 12 '15 at 17:21

2 Answers2

2

You could provide some default version in a namespace:

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);
}

And then with the magic of ADL, you can just provide a version of to_bool in the namespace of the class you want:

namespace whatever {
    struct linger { ... };

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

And then just use conv_bool everywhere:

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

If you provided your own to_bool() function, that will get preferred. Otherwise, the default one will get called which will try to do operator bool or some equivalent. No having to deal with template issues.

Barry
  • 286,269
  • 29
  • 621
  • 977
0

As operator bool can be only a method, not a standalone function, I think one of solutions is generating derived class from the one you want to cast to bool and implement only your operator there. This will work unless the class we are talking about is final.

class Boolable : public optType{
public:
    using optType::optType;
    operator bool() const{
        //your code her
    }
};
bartop
  • 9,971
  • 1
  • 23
  • 54
  • I think you mean "member function"... it does not have to be `virtual` (like a method) – Ben Voigt Jul 12 '15 at 18:39
  • @BenVoigt AFAIK method == member function. http://stackoverflow.com/questions/8596461/in-c-what-is-the-difference-between-a-method-and-a-function – bartop Jul 12 '15 at 19:10
  • No, they are not equivalent at all. I've seen two common definitions of "method" -- object-based (dynamic type) dispatch, which includes only virtual member functions, and static type-based dispatch, which doesn't have to be a member at all. – Ben Voigt Jul 12 '15 at 21:17
  • @BenVoigt So prove me wrong and give link with C++ proffessional showing difference. [A method is a piece of code that is called by name that is associated with an object. In most respects it is identical to a function except for two key differences. It is implicitly passed for the object for which it was called. It is able to operate on data that is contained within the class (remembering that an object is an instance of a class - the class is the definition, the object is an instance of that data).](http://stackoverflow.com/questions/155609/difference-between-a-method-and-a-function) – bartop Jul 13 '15 at 11:33