从过载集中检索指向最佳匹配的指针而不调用

时间:2011-11-23 19:44:23

标签: c++ boost boost-bind c++03

由于各种原因,我需要使用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的重载集中选择最佳匹配,但是转换是不同的,即使某些参数是可转换的,也无法找到完美的匹配。所以问题变成:是否有可能以某种方式得到类型和&amp;指向过载集的最佳匹配而不实际调用它?不能使用C ++ 03中没有的任何东西。

1 个答案:

答案 0 :(得分:3)

您可以利用延迟评估表达式模板。

AFAIK绑定表达式正好在该系列中(如Boost Proto epxressions,Spirit Grammar parse expression等)。

更新终于让我一起行动了。但是,它仅适用于具有重载operator()的可调用对象。我想你可以使用像胶这样的东西吗?

  • 我现在展示了C ++ 03和C ++ 11概念验证,这可能有助于在此基础上构建一个胶水仿函数
  • C ++ 03 接近等效(参见代码中的// TODO
  • C ++ 03版本依赖于Boost Typeof和Boost Bind(有关多态函数对象的结果类型的背景,请参阅Boost Utility doc for 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
}