调用函数时错误的参数转换优选
-
20-08-2019 - |
题
我写的Visual C ++ 6.0 MS下一个程序(是的,我知道这是古老的,没有有什么我可以做的升级)。我看到一些行为,我认为是很奇怪的。我有这样定义两个构造函数的一类:
class MyClass
{
public:
explicit MyClass(bool bAbsolute = true, bool bLocation = false) : m_bAbsolute(bAbsolute), m_bLocation(bLocation) { ; }
MyClass(const RWCString& strPath, bool bLocation = false);
private:
bool m_bAbsolute;
bool m_bLocation;
};
当我实例化该类与该语法的实例:MyClass("blah")
,它调用第一构造函数。正如你所看到的,我希望它不会做...没有骰子添加explicit
关键字吧。这样看来,从const char *
喜欢转换bool
在转换到RWCString
,其中有一个拷贝构造函数,这需要const char *
。它为什么要这样做呢?我会认为像这样给出了两个可能的选择,它会说这是不明确的。我能做些什么来阻止它这样做呢?如果有可能,我想避免必须显式转换strPath
参数的RWCString
,因为它会与文字一起使用了很多,这是一个很大的额外打字(加上一个非常容易犯的错误)。
解决方案
显式的构造函数是不是隐式转换的一部分,只是收件人不会在这里帮助。
有没有办法来控制转换的优先顺序,但你可以添加了一个const char *第二构造函数。 E.g:
class MyClass
{
public:
MyClass(bool bAbsolute = true, bool bLocation = false);
MyClass(const RWCString& strPath, bool bLocation = false);
MyClass(const char* strPath, bool bLocation = false);
private:
bool m_bAbsolute;
bool m_bLocation;
};
其他提示
安德提供的解决方案。我想告诉你的为什么的它不工作,你尝试过的方式。如果有两个可行的功能参数,然后将参数最匹配的一个被调用。第二要求用户定义的转换,同时第一只需要一个标准转换。这就是为什么编译器更喜欢第一个在第二。
如果您不;吨要保持铸造,然后在我看来,你可能不得不做出另一个构造函数是需要一个const char *
。这就是我可能会在这种情况下做的。
(不知道为什么你打的是你是不是通过其大部分使用的类型构造函数)。
编辑:
我看到别人已经张贴了这个,而我打字矿
不知道为什么它应该混淆为一个字符串和布尔参考?我已经看到了一个布尔值和一个int的问题。结果 你可以失去的默认值第一个构造 - 它可能是因为这是使其成为MyClass的(默认构造函数),那么它也是,如果它不能匹配ARGS默认
您的选择是增加一个构造函数,明确需要一个const char *
MyClass(const char* strPath, bool bLocation = false); // Thanks Andrew Grant!
或者做
MyClass( string("blah") );
在编译器内在知道如何使一个const char *成一个布尔值。它会去寻找,看看是否对任何第一个参数的类型MyClass的构造函数中,有将带你给它的源类型,或者如果可以将它转换为是由接受一个类型构造函数任何任何的第一参数类型的MyClass的构造函数的构造函数,或者......嗯,你看这是怎么回事,这就是只对第一个参数。这会带来疯狂。
在explicit
关键字告诉编译器不能自变量的类型的值转换为你的类的对象隐含的形式,在
struct C { explicit C( int i ): m_i(i) {}; int m_i; };
C c = 10;//disallowed
C c( 2.5 ); // allowed
C ++都有一套规则,以确定哪些构造函数是在你的情况被称为 - 我无法从我的后脑勺知道你,但你可以直观地看到默认的参数对不确定性导致
您需要通过考虑这些默认值。
您可以回退到一些静态的,命名,施工方法。或者你也可以使用不同的类(这是不是从设计角度来看一个不错的选择)。无论是哪种方式,你让客户端代码决定使用哪个构造。
struct C {
static C fromString( const char* s, const bool b = true );
static C fromBools( const bool abs = true, const bool b = true );
};
或
struct CBase {
bool absolute;
bool location;
CBase( bool abs=true, bool loc=true );
};
struct CBaseFromPath {
// makes 'absolute' true if path is absolute
CBaseFromPath( const char* s, const bool loc );
};
您的某些,这确实是调用第一个构造函数?你用字符串硬编码调用它,还是它隐藏在背后#define
?你确定#定义是什么,你认为它是什么? (尝试使用/ Ef中选项编译得到扩展预处理器输出,并查看是否调用看起来像你希望它看起来。)
编辑:在此基础上和其他的意见,我的建议是添加另一个构造函数const char*.
那是可行的。