我在使用C ++重载方法时遇到了一些麻烦。 作为问题的一个例子,我有一个类,其中有许多方法被重载,并且每个方法都有一个具有不同数据类型的参数。 我的问题:这些方法应该出现在类中的特定顺序,以确保根据其参数数据类型调用正确的方法吗?
class SomeClass{
public:
...
void Method(bool paramater);
void Method(std::string paramater);
void Method(uint64_t paramater);
void Method(int64_t paramater);
void Method(uint8_t paramater);
void Method(int8_t paramater);
void Method(float paramater);
void Method(double paramater);
void Method(ClassXYZ paramater);
}
我注意到有问题,因为在跑步时:
Method("string");
它在呼唤:
Method(bool paramater);
答案 0 :(得分:23)
订单没有区别。通过分析参数的类型并将它们与参数类型相匹配来选择要调用的方法。如果没有完全匹配,则选择最佳匹配方法。在您的情况下,它恰好是bool
方法。
您正在提供const char[7]
类型的参数。根据C ++重载规则,这里的最佳路径是让const char[7]
衰减到const char *
,然后使用标准转换将其转换为bool
。转换为std::string
的路径被认为更糟糕,因为它涉及从const char *
到std::string
的用户定义转换。通常,用户定义的转换会丢失标准转换的重载解析过程。这也是你的情况。
如果您需要在此处调用std::string
版本,请为const char *
类型提供显式重载,并通过将参数转换为std::string
将调用委托给std::string
版本明确地输入
void Method(const char *paramater /* sic! */)
{
Method(std::string(paramater));
}
答案 1 :(得分:5)
字符串文字"string"
的类型const char[]
可以隐含转换为bool
。这是你的一个重载函数的最佳转换候选者,尽管它不太可能是最有用的函数。
如果您的意图是使用std::string
的重载来处理字符串文字,那么您需要添加一个带有const char*
的重载并使实现调用std::string
版本
答案 2 :(得分:4)
订单并不重要。这里的问题是当你调用
时Method("string");
您正在传递一个const char []。这将隐式转换为bool。你想要做的是显式传递一个std :: string:
Method( std::string("string"));
答案 3 :(得分:2)
没有回答你的问题但是,出于好奇,有没有使用模板方法而不是为每种类型定义重载版本的隐藏原因?
class SomeClass
{
public:
...
template <typename T>
void Method(T paramater);
};
答案 4 :(得分:1)
正如Charles已经指出的那样,这是由于不必要的隐式转换而发生的。如果你想避免这种情况,请使用std :: string构造函数:
Method(std::string("string"));
或者将它转换为std :: string:
Method(static_cast<std::string>("string"));
但是,声明的顺序并不重要。还要检查拼写单词“parameter”;)
答案 5 :(得分:1)
除了字符串问题外,还有另外一个问题。 int64_t和int8_t(通常)是typedef。由于typedef只是别名,因此它们可能引用相同的类型,在这种情况下,重载将不起作用。但在你的情况下,这是不太可能的。只是想提一下。
答案 6 :(得分:1)
您可以添加 explict 关键字,以便获取预期的参数。