检查函数签名也继承功能 [英] Check for function signature also for inherited functions

查看:140
本文介绍了检查函数签名也继承功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要检查,如果一个货柜擦除函数返回迭代器。我通常检查通过例如函数签名促进。但是,在升压级的情况下(例如flat_set)擦除继承,因此不会被检查发现。但我真的需要它。 <一href=\"https://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions\">SFINAE检查继承成员函数只能说明我还不能使用C ++ 11的解决方案。

我想是这样的:

 模板&LT; typename的T&GT;
    类has_member_func_erase_it_constit
    {
        的typedef typename的T ::迭代器迭代器;
        的typedef typename的T ::为const_iterator为const_iterator;
        的typedef BOOST_TYPEOF_TPL(&amp; T公司::擦除)eraseType;        的typedef typename的提振:: function_types :: result_type的&LT; eraseType&GT; ::类型的搜索结果;
    上市:
        静态常量布尔值=提振:: is_same&LT;迭代器,导致&GT; ::值;
    };    模板&LT;类T&GT;
    结构EraseReturnsIterator
    {
        静态CONSTEXPR布尔值= has_​​member_func_erase_it_constit&LT; T&GT; ::值;
    };

但由于擦除过载失败。我可能会需要decltype或类似的东西,以检查与常量性抹去编译时调用的返回类型,但我不能找到一个。

这怎么可能在pre C ++ 11?

如果有一个擦除功能返回void这也并不工作:​​

 模板&LT; typename的T&GT;
    类has_member_func_erase_it
    {
        的typedef typename的T ::迭代器迭代器;
        的typedef typename的T ::为const_iterator为const_iterator;        的typedef CHAR是[1];
        焦炭的typedef无[2];        静态ŧMAKET();
        静态迭代makeIt();        的typedef BOOST_TYPEOF_TPL(MAKET()擦除(makeIt()))的结果;    上市:
        静态常量布尔值=提振:: is_same&LT;迭代器,导致&GT; ::值;
    };


解决方案

以下工作:

  ///房屋类型
    模板&LT; typename的T&GT;结构Type2Type {
        typedef的T形;
    };    ///邪恶两轮牛车把一个前pression成式
    模板&LT; typename的T&GT;
    Type2Type&LT; T&GT;运营商(T,Type2Type&LT;无效&GT;);    模板&LT; typename的T&GT;
    ŧdeclval();    模板&LT;类T&GT;
    结构EraseReturnsIterator
    {
        的typedef typename的T ::迭代器迭代器;
        的typedef BOOST_TYPEOF_TPL((declval&LT; T&GT;()擦除(declval&LT;&迭代器GT;()),&Type2Type LT;无效&GT;()))的结果;        静态CONSTEXPR布尔值=提振:: is_same&LT;迭代器,类型名称结果::类型&GT; ::值;
    };

Basicly我们只需要调用的返回类型,我们需要的功能。如果没有这种类型的函数返回永远比无效就BOOST_TYPEOF_TPL已经工作。不幸的是擦除可以返回无效,因为它试图通过打破实行无效&安培;某处堆栈。

因此​​,为了避免虚空(没有双关语意),我们把它放在一个类型,即持有型。为了能够为前pressions做到这一点,我们重载逗号操作符。这样的结果等于Type2Type,我们可以轻松地阅读。完成!

理念为逗号过载: http://stackoverflow.com/a/5553460/1930508

I need to check, if a containers erase function returns the iterator. I'd normally check for the function signature via e.g. boost. But in case of a boost class (e.g. flat_set) erase is inherited and thus not found by the check. But I really need it. SFINAE to check for inherited member functions only shows a C++11 solution which I can't use yet.

I tried something like this:

    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;
    };

But it fails since erase is overloaded. I'd probably need decltype or something like that to check the return type from a compile-time invocation of erase with const_iterator, but I can't find one.

How is this possible in pre C++11?

This does also not work if there is an erase function returning 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; 
    };

解决方案

The following works:

    /// "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;
    };

Basicly we just call the function whose return type we need. If no function of this type ever returned void than BOOST_TYPEOF_TPL would already work. Unfortunately erase CAN return void which breaks the implementation as it tries to pass "void&" somewhere down the stack.

So to avoid the void (no pun intended) we put it in a type, that holds a type. To be able to do this for expressions, we overload the comma operator. This way result equals "Type2Type" which we can easily read. Done!

Idea for the comma-overload: http://stackoverflow.com/a/5553460/1930508

这篇关于检查函数签名也继承功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆