背景
如果第三方库的代码类似
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
是一个允许与流操作符进行交互的类型包装器。
答案 0 :(得分:1)
当我开始这个问题时,我怀疑由于其他类似的SO答案,我无法得到我想要的东西。
当我完成问题时,我想出了一个适合我需要的工作,它并不是真正明确的转换,所以你的里程可能会根据你需要达到的目标而有所不同。
我想如果有人发现它有用,我也可以发布它。
解决方法
添加以下定义:
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
。
答案 1 :(得分:1)
当将参数与参数匹配并选择函数重载时,C ++允许一系列隐式转换。但序列中只允许一个“用户定义”转换(涉及函数调用)。传递字符串文字需要std::string::string( char const * )
和ThirdPartyClass::ThirdPartyClass( std::string const & )
,这是两个函数。 C ++不允许这样做,因为无限制的转换会使编译器变慢并产生不可预测的结果。
您已经通过定义其他函数重载找到了一种解决方法,因此如果可行,请选择它:v)。