检查继承功能的功能签名

时间:2015-08-05 21:45:54

标签: c++ boost traits template-meta-programming c++03

我需要检查,如果容器擦除函数返回迭代器。我通常会通过例如检查功能签名来检查促进。但是在增强类(例如flat_set)的情况下,擦除被继承,因此检查不能找到。但我真的需要它。 SFINAE to check for inherited member functions只显示了我还不能使用的C ++ 11解决方案。

我试过这样的事情:

    template <typename T> 
    class has_member_func_erase_it_constit
    { 
        typedef typename T::iterator iterator;
        typedef typename T::const_iterator const_iterator;
        typedef BOOST_TYPEOF_TPL(&T::erase) eraseType;

        typedef typename boost::function_types::result_type<eraseType>::type result;
    public: 
        static const bool value = boost::is_same<iterator, result>::value; 
    };

    template<class T>
    struct EraseReturnsIterator
    {
        static CONSTEXPR bool value = has_member_func_erase_it_constit<T>::value;
    };

但由于擦除过载,它失败了。我可能需要使用decltype或类似的东西来检查使用const_iterator进行擦除的编译时调用的返回类型,但我找不到。

在C ++ 11之前这怎么可能?

如果存在返回void的擦除函数,则这也不起作用:

    template <typename T> 
    class has_member_func_erase_it
    { 
        typedef typename T::iterator iterator;
        typedef typename T::const_iterator const_iterator;

        typedef char yes[1];
        typedef char no [2];

        static T makeT();
        static iterator makeIt();

        typedef BOOST_TYPEOF_TPL(makeT().erase(makeIt())) result;

    public: 
        static const bool value = boost::is_same<iterator, result>::value; 
    };

1 个答案:

答案 0 :(得分:0)

以下作品:

    /// "Stores a type"
    template<typename T> struct Type2Type{
        typedef T type;
    };

    /// Evil hackery to put an expression into a type
    template<typename T>
    Type2Type<T> operator,(T, Type2Type<void>);

    template<typename T>
    T declval();

    template<class T>
    struct EraseReturnsIterator
    {
        typedef typename T::iterator iterator;
        typedef BOOST_TYPEOF_TPL((declval<T>().erase(declval<iterator>()), Type2Type<void>())) result;

        static CONSTEXPR bool value = boost::is_same<iterator, typename result::type>::value;
    };

基本上我们只调用我们需要的返回类型的函数。如果此类型的函数没有返回void,则BOOST_TYPEOF_TPL已经有效。不幸的是,擦除CAN返回void会破坏实现,因为它试图通过&#34; void&amp;&#34;在堆栈的某个地方。

所以为了避免虚空(没有双关语),我们把它放在一个类型中,它有一个类型。为了能够为表达式执行此操作,我们重载逗号运算符。这种结果等于&#34; Type2Type&#34;我们可以轻松阅读。完成!

逗号重载的想法:https://stackoverflow.com/a/5553460/1930508