kyb February 2016

Conversion is ambiguous. Standard implicit conversion could not choose cast operator

I have a custom type described as

struct A {
    double dbl_;
    bool boo_;
    operator double() const { return dbl_; }
    //operator bool() const { return boo_; }
};

And now I want to cast it to simple types. When operator bool() is undefined a can be implicitly converted to any simple type int, unsigned, float, etc. But with operator bool() conversion is ambiguous.

A a;
cout << (double) a << endl;
cout << (float) a << endl; //error: conversion from 'A' to 'float' is ambiguous; candidates are: A::operator bool() const; A::operator double() const
cout << (int) a << endl;  // the same
cout << (char) a << endl; // the same
return 0;

Runnable code on cpp.sh

I know a few ways to fix that:

1.add type conversion operators for all the expected types.

 operator int() const { return (int)dbl_; }
 // and so on...

This looks like bad practice.

2.use template with restricted types.

template<class T, class...> struct is_any_of: std::false_type{};
template<class T, class Head, class... Tail>
struct is_any_of<T, Head, Tail...> : std::conditional<
        std::is_same<T, Head>::value,
        std::true_type,
        is_any_of<T, Tail...> >::type
{};

template<
        class T,
        class = typename std::enable_if<is_any_of<T, int, float, unsigned, double>::value>::type
>
operator T() const {
    if(type_ != Type::NUMBER) throw Node::Exception("not is number");
    return dbl_;
}

3.Hold bool value in dbl_, because only one of them is used. Not cool, as for me.

Answers


BarryTheHatchet February 2016

Making all your conversion operators explicit (to prevent implicit conversions) would be a good start:

struct A {
    double dbl_;
    bool boo_;
    explicit operator double() const { return dbl_; }
    explicit operator bool() const { return boo_; }
};

I'm not sure, but I imagine this would help to prevent the ambiguities too.

Post Status

Asked in February 2016
Viewed 2,714 times
Voted 6
Answered 1 times

Search




Leave an answer