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 表达式、Spirit Grammar 解析表达式等也是如此)。

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

  • 我现在展示了 C++03 和 C++11 的概念证明,它们可能有助于围绕这个构建胶函子
  • C++03几乎等价(参见// TODO代码中的)
  • C++03 版本依赖于 Boost Typeof 和 Boost Bind(有关多态函数对象的结果类型的背景信息,请参见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 回答