在第三方库中扩展隐式转换

Extend implicit conversion in 3rd party library

本文关键字:转换 扩展 第三方      更新时间:2023-10-16

背景

如果第三方库具有

的代码
class ThirdPartyClass
{
public:
    int value;
    ThirdPartyClass(int i) : value(i) {}
    ThirdPartyClass(const std::string& s) : value(0) {}
};
bool ThirdPartyFunction(int a, const ThirdPartyClass obj)
{
    return a == obj.value;
}

然后可以像

一样呼叫
ThirdPartyFunction(1, 1);
ThirdPartyFunction(1, std::string("Hello, World!"));

问题

是否可以扩展此库(不修改第三方代码)接受以下内容:

ThirdPartyFunction(1, "Hello, World!");   // const char* is not a string, implicit conversion fails

我想避免需要写

ThirdPartyFunction(1, std::string("Hello, World!")); 

上面的简化:在我的真实示例中,ThirdPartyFunction是流操作员,ThirdPartyClass是允许与流操作器交互的类型包装器。

当我开始这个问题时,我怀疑不可能得到我想要的东西,因为还有其他类似的答案。

到我完成问题的时候,我提出了适合我需求的工作,这并不是很明确的转换,因此您的里程可能会根据您需要实现的准确而有所不同。

我认为我不妨将其发布,以防万一有人觉得它有用。

围绕

工作

添加以下定义:

class MyExtension : public ThirdPartyClass
{
public:
    MyExtension(const char*) : ThirdPartyClass(0) {}
};
bool ThirdPartyFunction(int a, MyExtension obj)
{
    return ThirdPartyFunction(a, (ThirdPartyClass)obj);
}

现在可以致电

ThirdPartyFunction(1, "Hello, World!");

请注意,可以在不修改第三方代码的情况下完成上述操作。它确实依赖于使功能超载,因此,如果您必须为许多功能执行此操作,则可能是不可行的。您也可以避免继承,并且只需在重载函数中从MyExtension转换为ThirdPartyClass

c 允许将参数与参数匹配并选择函数过载时进行一系列隐式转换。但是,序列中只允许使用一个"用户定义"转换(涉及函数调用)。传递字符串字面形式将需要std::string::string( char const * )ThirdPartyClass::ThirdPartyClass( std::string const & ),这是两个函数。C 将其否定为无限转换将使编译器缓慢并产生不可预测的结果。

您已经通过定义其他功能过载来找到解决方法,因此,如果可行,请进行:v)。