【问题标题】:Extend implicit conversion in 3rd party library在 3rd 方库中扩展隐式转换
【发布时间】:2012-11-09 04:49:49
【问题描述】:

背景

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

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;
}

那么就可以调用like了

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 是一个允许与流操作符交互的类型包装器。

【问题讨论】:

  • 是的。编辑以使问题脱颖而出。

标签: c++ explicit-conversion


【解决方案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

【讨论】:

    【解决方案2】:

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

    您已经通过定义额外的函数重载找到了一种解决方法,所以如果可行,那就去做吧:v)。

    【讨论】:

    • +1 用于解释两个用户定义的转换部分。以前我真的不明白。
    猜你喜欢
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 2017-04-13
    • 2012-01-08
    • 2019-01-21
    • 2015-02-23
    • 1970-01-01
    • 2021-01-06
    相关资源
    最近更新 更多