2

背景

如果第三方库有类似的代码

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!"));

问题

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

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

我想避免需要写

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

以上是简化的:在我的真实示例ThirdPartyFunction中是一个流操作符,并且ThirdPartyClass是一个允许与流操作符交互的类型包装器。

4

2 回答 2

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!");

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

于 2012-11-09T04:49:49.490 回答
1

在将参数与参数匹配并选择函数重载时,C++ 允许进行一系列隐式转换。但是序列中只允许进行一次“用户定义的”转换(涉及函数调用)。传递字符串文字需要std::string::string( char const * )and ThirdPartyClass::ThirdPartyClass( std::string const & ),这是两个函数。C++ 不允许这样做,因为无限制的转换会使编译器变慢并产生不可预测的结果。

You have found a workaround by defining additional function overloads, so if that's viable, go for it :v) .

于 2012-11-09T05:00:03.330 回答