stdd :: bind()のstatic_castのファンチャーバージョン
-
26-10-2019 - |
質問
のファンクターバージョンを実装しようとしています static_cast
で使用するため std::bind()
.
ブーストを知っています ll_static_cast<K>()
(見る boost :: bindでstatic_castを使用します)、しかし、私は今ブーストを使用していません。
コードの例があります なぜいくつかの標準オペレーターに標準的な機能を持っていないのですか? しかし、GCC 4.2.1でコンパイルされません:
template <typename Target>
struct StaticCast
{
template <typename Source>
Target operator()(Source&& source) const
{
return static_cast<Target>(source);
}
}
コンパイルするものを手に入れることができましたが、それが正しいかどうかはわかりません:
template <class Target>
struct StaticCast : public std::unary_function<void, Target> {
template <class Source>
Target operator()(Source& src) const {
return static_cast<Target>(src);
}
};
このバージョンが正しいかどうか、そしてもしそうなら、なぜ必要なのか教えてもらえますか std::unary_function
前のコードの例では使用されていませんか?
使用法:
std::vector<BaseObject*> vec; // BaseObject* are known to be of type
// DerivedObject* of course, please don't ask me how or why...
std::for_each(vec.begin(), vec.end(),
std::bind(&DerivedObject::doStuff,
std::bind(StaticCast<DerivedObject*>(), std::placeholders::_1),
"with some string"));
解決
C ++ 03での完全な転送がないことを考えると、過負荷を使用する必要があります。
template<class Target>
struct StaticCast
{
typedef Target result_type;
template<class Source>
Target operator ()(Source& src) const
{
return static_cast<Target>(src);
}
template<class Source>
Target operator ()(Source const& src) const
{
return static_cast<Target>(src);
}
};
明示的に作成していることに注意してください typedef
為に result_type
継承するのではなく std::unary_function<>
. 。その理由は、最初のテンプレートパラメーターです std::unary_function<>
あるはずです operator()
'の引数タイプですが、私たちのからです operator()
事前にこれを知ることができないテンプレートなので、そもそもそれを提供することは不誠実です(特に void
, 、それはそれを意味します operator()
実際、それが統一されている場合)です。
また、完全性のために、ここにファンクターの正しいC ++ 11バージョンがあります:
template<class Target>
struct StaticCast
{
template<class Source>
Target operator ()(Source&& source) const
{
return static_cast<Target>(std::forward<Source>(source));
}
}
他のヒント
最初の1つが機能しない理由の1つは、おそらくC ++ 11をサポートしていないコンパイラでRValue参照を使用しているためです。
あなたが必要とする理由 std::unary_function
有効にすることです std::result_of
あなたのクラスのために std::bind
C ++ 98には逆タイプがないため、結果タイプを推定するために使用します。
あなたが見たら std::unary_function
タイプを定義していることがわかります result_type
あなたが渡すテンプレート引数から、それは std::result_of
また std::bind
直接。
まあ、一般的にあなたのコードは悪いです:
まず、それらの非コンスト参照を要求しながら、一時的なオブジェクトとR値で問題があるかもしれません
例えば
float f = StaticCast<float>()(4);
コンパイルさえしません。
次にあなた コピーを作成します キャスト中のオブジェクトの。それはあなたが望むものではないかもしれません。
ソースの例 自由 その欠点の move
セマンティクス