我有一个Parameter类,我重载了构造函数以接受bools或double。当你给它一个int时,它无法构建:
错误C2668:'参数::参数':对重载的模糊调用 功能可以 '参数::参数(std :: string,std :: string,double)'或
'参数::参数(的std :: string,的std :: string,布尔)'
我相信我有两个选择:
我有大量的参数,其中一些是无符号长,浮点数等(在多人支持的项目中),所以这些都不是完美的解决方案。有没有办法强制从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
}
答案 0 :(得分: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;}
或者也许在模板参数列表中执行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;}
答案 1 :(得分:1)
您可以使用traits模板实现此操作,以使正确的强制转换为双倍。
#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
进行适当的转换。
答案 2 :(得分:-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,则会出现编译错误。
其他答案使用此技术的更高级版本,允许您T
仅匹配某些类型(与我的版本相比,它匹配每种类型但如果使用无效类型则会出错)