質問

Background

If a third party library has code like

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

Then it is possible to call like

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

Question

Is it possible to extend this library (without modifying 3rd party code) to accept something like:

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

I want to avoid needing to write

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

The above is simplified: in my real example ThirdPartyFunction is a stream operator and ThirdPartyClass is a type wrapper that allows interaction with stream manipulators.

役に立ちましたか?

解決

When I started this question I suspected it wasn't possible to get what I want, because of other similar SO answers.

By the time time I finished the question I came up with a work around that's suits my needs, it is not really explicit conversion, so your mileage may vary depending on exactly what you need to achieve.

I thought I might as well post it in case someone finds it useful.

Work around

Add the following definitions:

class MyExtension : public ThirdPartyClass
{
public:
    MyExtension(const char*) : ThirdPartyClass(0) {}
};

bool ThirdPartyFunction(int a, MyExtension obj)
{
    return ThirdPartyFunction(a, (ThirdPartyClass)obj);
}

Now it is possible to call

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

Note the above can be done without modifying third party code. It does rely on overloading the function, so if you had to do this for many functions it might not be feasible. You could also avoid the inheritance, and just convert from MyExtension to ThirdPartyClass in the overloaded function.

他のヒント

C++ allows for a sequence of implicit conversions when matching arguments to parameters and selecting a function overload. But only one "user-defined" conversion (involving a function call) is allowed in the sequence. Passing the string literal would require std::string::string( char const * ) and ThirdPartyClass::ThirdPartyClass( std::string const & ), which are two functions. C++ disallows this as unlimited conversions would make the compiler slow and produce unpredictable results.

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top