1

static_castで使用するのファンクター バージョンを実装しようとしていますstd::bind()

Boost は知っていますが( boost::bind で static_cast を使用するをll_static_cast<K>()参照)、現在は Boost を使用していません。

Why do some of the standard operator not have standard functor?にコード例があります。しかし、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"));
4

3 に答える 3

1

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

から継承するのではなく、明示的にtypedeffor を作成していることに注意してください。その理由は、 への最初のテンプレート パラメータがの引数の型であると想定されているためですが、私たちのはテンプレートであるため、事前にこれを知ることができないため、最初に 1 つを指定するのは不誠実です (特に、実際には単項ですが、nullary です)。result_typestd::unary_function<>std::unary_function<>operator()operator()voidoperator()


また、完全を期すために、ファンクターの正しい C++11 バージョンを次に示します。

template<class Target>
struct StaticCast
{
    template<class Source>
    Target operator ()(Source&& source) const
    {
        return static_cast<Target>(std::forward<Source>(source));
    }
}
于 2012-01-10T17:03:37.517 に答える
0

最初の方法が機能しない理由の 1 つは、おそらく、C++11 をサポートしていないコンパイラで右辺値参照を使用しているためです。

必要な理由は、C++98 には decltype がないため、結果の型を推測するために使用するクラスをstd::unary_function有効にするためです。std::result_ofstd::bind

見ると、渡すテンプレート引数からstd::unary_function型を定義していることがわかります。これは、または直接使用されます。result_typestd::result_ofstd::bind

于 2012-01-10T16:28:33.597 に答える
0

まあ、一般的にあなたのコードは悪いです:

まず、非 const 参照を要求する際に、一時オブジェクトと r 値に問題が発生する可能性があります。

例えば

float f = StaticCast<float>()(4);

コンパイルすらしません。

次に、キャスト中にオブジェクトのコピーを作成します。それはあなたが望んでいないかもしれません。

セマンティクスによるその欠点のないソースmove

于 2012-01-10T16:41:30.590 に答える