4

我有一个 Parameter 类,并且我重载了构造函数以接受 bool 或 double。当你给它一个 int 时,它无法构建:

错误 C2668:“Parameter::Parameter”:对重载函数的模糊调用可能是“Parameter::Parameter(std::string,std::string,double)”或
“Parameter::Parameter(std::string,std: :字符串,布尔)'

我相信我有两个选择:

  1. 使用 int 默认值重载
  2. 将我的变量显式转换为双精度

我有很多参数,其中一些是 unsigned long、float 等(在一个多人支持的项目中),所以这些都不是完美的解决方案。有没有办法强制从 int 到 double 的隐式转换?谢谢。

代码:

#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 回答 3

3

如果您想从考虑中删除带有bool最终元素的 ctor,除非它是显式的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_tdecay_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;}
于 2014-08-12T20:56:26.643 回答
1

您可以使用特征模板来实现这一点,以进行适当的双重转换。

#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
}

这非常适合您的场景:我有大量参数,其中一些是无符号长整数、浮点数等...很容易添加更多特征(DFTtrait 实现)以满足您的所有需求,例如,如果您添加:

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

您的代码将自动支持long long int并正确转换为double.

于 2014-08-12T20:52:34.607 回答
-1

一个非常简单的版本是对构造函数使用模板参数,并使用非模板重载bool(以及您不想转换为双精度的任何其他类型):

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,那么您将收到编译器错误。

其他答案使用此技术的更高级版本,以允许您T仅匹配某些类型(与我的版本相反,它匹配每种类型,但如果使用无效类型,则会出现错误)。

于 2014-08-13T21:57:00.500 回答