从重载集检索指向最佳匹配项的指针,而不调用

Retrieve pointer to best match from overload set without calling

本文关键字:指针 调用 重载 检索 最佳      更新时间:2023-10-16

由于各种原因,我需要使用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中没有的东西

可以利用延迟求值表达式模板。

AFAIK绑定表达式正是属于这类表达式(Boost Proto表达式、Spirit Grammar解析表达式等也是如此)。

Update终于让我振作起来了。然而,它只适用于重载了操作符()的可调用对象。我想你可以把这种东西当胶水用吧?

  • 我现在展示c++ 03和c++ 11的概念证明,这可能有助于围绕这个
  • 构建一些粘合函子。
  • c++ 03的相当(参见代码中的// TODO)
  • c++ 03版本依赖于Boost Typeof和Boost Bind(参见Boost Utility doc for result_of关于多态函数对象结果类型的背景)
  • 两个版本都在IdeOne上运行

c++ 03 (live on 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 (live on 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
}