2

さまざまな理由から、2 フェーズ構成を使用する必要があります。さらに、最後のフェーズは延期され、別のスレッドによって実行されます。コンテキスト:

...
#define BOOST_PP_LOCAL_MACRO(n) \
        template < typename ConnectionType, BOOST_PP_ENUM_PARAMS(n, typename T) > \
        boost::shared_ptr< ConnectionType > Connect( BOOST_PP_ENUM_BINARY_PARAMS(n, T, arg) ) \
        { \
            boost::shared_ptr< ConnectionType > con( boost::make_shared< ConnectionType >() ); \
            boost::mutex::scoped_lock sl( m_AddNetworkJobMutex ); \
            m_NetworkJobs.push_back( boost::bind( static_cast< void ( ConnectionType::* )( BOOST_PP_ENUM_PARAMS(n,T) ) >( &ConnectionType::Init ), con, BOOST_PP_ENUM_PARAMS(n, arg) ) ); \
            return con; \
        } 

#define BOOST_PP_LOCAL_LIMITS (1, 5)
#include BOOST_PP_LOCAL_ITERATE()
...

ここでの問題は、ConnectionType::Init に設定されたオーバーロードから可能な限り一致するものを選択したいのですが、キャストが異なり、一部の引数が変換可能であっても完全に一致するものを見つけることができないことです。したがって、質問は次のようになります:実際に呼び出すことなく、オーバーロード セットから最適な一致する型とポインターを何らかの形で取得することは可能ですか? C++03 で使用できないものは使用できません。

4

1 に答える 1

3

遅延評価式テンプレートを活用できます。

AFAIKバインド式は、まさにそのファミリに含まれます(Boost Proto epxressions、Spirit Grammar解析式なども同様です)。

アップデートはついに私の行動をまとめました。ただし、オーバーロードされたoperator()を持つ呼び出し可能なオブジェクトでのみ機能します。このようなものを接着剤として使用できると思いますか?

  • ここで、C++03とC++11の両方の概念実証を示します。これは、この周りに接着剤ファンクターを構築するのに役立つ可能性があります。
  • C ++ 03はほぼ同等です(// TODOコードのを参照)
  • C ++ 03バージョンは、BoostTypeofとBoostBindに依存しています(ポリモーフィック関数オブジェクトの結果タイプの背景については、 Boost Utilityのドキュメントを参照してください)。result_of
  • どちらのバージョンもIdeOneにあります

C ++ 03(https://ideone.com/VHcECでライブ)

これは、C ++ 11デモ(下記)のC ++ 03+Boostへの部分的な移植です。

#include <string>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/typeof/typeof.hpp>

struct overloaded
{
    typedef int result_type;

    int operator()(const std::string& s) const { return 1; }
    int operator()(double d)             const { return 2; }
};

struct factory
{
    template <typename T> struct result { typedef BOOST_TYPEOF_TPL(boost::bind(overloaded(), T())) type; };

    template <typename T>
    typename result<T>::type operator()(const T& t) const 
    {
        return boost::bind(overloaded(), t);
    }
};

int main()
{
    overloaded foo;

    // based on local bind expression:
    BOOST_AUTO(unresolved, boost::bind(foo, _1));
    std::cout << unresolved("3.14") << std::endl;  // should print 1
    std::cout << unresolved(3.14)   << std::endl;  // should print 2

    // based on a factory function template
    factory makefoo;
    std::string str("3.14"); // TODO get rid of this explicit instanciation?
    std::cout << makefoo(str)() << std::endl;  // should print 1
    std::cout << makefoo(3.14)()   << std::endl;  // should print 2
}

C ++ 11(https://ideone.com/JILEAでライブ)

簡単な例として、これは問題なく機能するはずです。

#include <string>
#include <iostream>
#include <functional>

using namespace std::placeholders;

struct overloaded
{
    int operator()(const std::string& s) const { return 1; }
    int operator()(double d)             const { return 2; }
};

template <typename T>
auto makefoo(const T& t) -> decltype(std::bind(overloaded(), t))
{
    return std::bind(overloaded(), t);
}

int main()
{
    overloaded foo;

    // based on local bind expression:
    auto unresolved = std::bind(foo, _1);
    std::cout << unresolved(3.14)   << std::endl;  // should print 2
    std::cout << unresolved("3.14") << std::endl;  // should print 1

    // based on a factory function template
    std::cout << makefoo(3.14)()   << std::endl;  // should print 2
    std::cout << makefoo("3.14")() << std::endl;  // should print 1
}
于 2011-11-23T19:50:19.253 に答える