Ambiguous call: int double or bool

I have a Parameter class and I overloaded the constructor to accept bools or double. When you give it an int, it cannot build:

error C2668: "Parameter :: Parameter": an ambiguous call to overload can be 'Parameter :: Parameter (std :: string, std :: string, double)' or
'Parameter :: Parameter (std :: string, st :: string , BOOL)

I believe that I have two options:

  • Overload with default
  • Explicitly convert my variable to double

I have a ton of parameters, and some of them are unsigned long, float, etc. (in support of several projects), so none of them is an ideal solution. Is there a way to force an implicit conversion from int to double? Thank.

the code:

#include <string>
#include <unordered_map>
using namespace std;

class Parameter
{
public:
    enum eVarType { BOOL, NUMBER};

    Parameter() {};
    Parameter( string param_name, string param_description, bool dft ) { type_ = BOOL;};
    Parameter( string param_name, string param_description, double dft ) { type_ = NUMBER;};
private:
    eVarType type_;
};

class ParameterManager
{
public:
    template<typename T> void add( string option_name, string description, T value );
private:
    std::unordered_map< string, Parameter > parameters;
};

template<typename T> void ParameterManager::add( string param, string description, T value )
{
    parameters[param] = Parameter( param, description, value );
};

int main()
{
    ParameterManager mgr;
    int var = 1;
    mgr.add("number","This is an int",var); //Could be double or bool: I want it to be a double
}
+4
3

ctor bool , bool, SFINAE:

template<class X>
Parameter( string , string , X  ,
    enable_if_t<is_same<decay_t<X>, bool>::value, int> = 0)
{ type_ = BOOL;}

. coliru.

, , SFINAE :

template<class X,
    enable_if_t<is_same<decay_t<X>, bool>::value, nullptr_t> = nullptr>
Parameter( string , string , X ) { type_ = BOOL;}

enable_if_t decay_t:

template<class X>
Parameter( string , string , X ,
    typename enable_if<is_same<typename decay<X>::type,
    bool>::value, int>::type = 0)
{ type_ = BOOL;}
template<class X,
    typename enable_if<is_same<typename decay<X>::type,
    bool>::value, nullptr_t>::type = nullptr>
Parameter( string , string , X)
{ type_ = BOOL;}
+3

, , .

#include <string>
#include <unordered_map>
using namespace std;

class Parameter
{
public:
    enum eVarType { BOOL, NUMBER };

    Parameter() {};
    Parameter(string param_name, string param_description, bool dft) { type_ = BOOL; };
    Parameter(string param_name, string param_description, double dft) { type_ = NUMBER; };
private:
    eVarType type_;
};

// Traits definitions.
template<typename T> struct DFTtrait;

template<> struct DFTtrait<double> 
{typedef double Type;};

template<> struct DFTtrait<bool>
{typedef bool Type;};

// Here is the key. When it receives an int
// the type is set to double.
template<> struct DFTtrait<int>
{typedef double Type;};



class ParameterManager
{
public:
    template<typename T, typename cast_t = DFTtrait<T>::Type> void add(string option_name, string description, T value);
private:
    std::unordered_map< string, Parameter > parameters;
};

template<typename T, typename cast_t> void ParameterManager::add(string param, string description, T value)
{
    parameters[param] = Parameter(param, description, (cast_t)value);
};



int main()
{
    ParameterManager mgr;
    int var = 1;
    mgr.add("number", "This is an int", var); // Now DFTtrait<T>::Type is evaluated to double
                                              // hence, (cast_t)value == (double)value when T == int
}

: , long, floats ..... ( DFTtrait) , , :

template<> struct DFTtrait<long long int>
{typedef double Type;};

long long int double.

+1

bool ( , double):

Parameter( string param_name, string param_description, bool dft ) { type_ = BOOL;}
// note, no trailing semicolon required for inline method definitions

template<typename T>
Parameter( string param_name, string param_description, T dft )
{ 
    type_ = NUMBER;
    value = static_cast<double>(dft);
}

( " " - dft).

double, .

Other answers use more advanced versions of this method, which are allowed Tonly for certain types (unlike my version, where it corresponds to each type, but then you get an error if invalid types are used).

-1
source

All Articles