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

質問

このライブラリを (サードパーティのコードを変更せずに) 拡張して、次のようなものを受け入れることは可能ですか?

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

上記は、サードパーティのコードを変更せずに実行できることに注意してください。関数のオーバーロードに依存しているため、多くの関数に対してこれを行う必要がある場合、実行できない可能性があります。継承を回避し、オーバーロードされた関数でからMyExtensionに変換することもできます。ThirdPartyClass

于 2012-11-09T04:49:49.490 に答える
1

C++ では、引数をパラメーターに一致させ、関数のオーバーロードを選択するときに、一連の暗黙的な変換が可能です。ただし、シーケンス内で許可される「ユーザー定義」変換 (関数呼び出しを含む) は 1 つだけです。文字列リテラルを渡すには、2 つの関数である とstd::string::string( char const * )が必要です。ThirdPartyClass::ThirdPartyClass( std::string const & )C++ では、無制限の変換によってコンパイラが遅くなり、予測できない結果が生じるため、これが許可されていません。

追加の関数オーバーロードを定義することで回避策を見つけたので、それが実行可能な場合は、それを試してください :v) 。

于 2012-11-09T05:00:03.330 に答える