胡撸娃哈哈 2021-03-12 14:56 采纳率: 0%
浏览 88

C++11 对set集合使用transform和negate方法编译报错

环境:C++11 ;Apple clang version 12.0.0 (clang-1200.0.32.29)

代码:

#include <algorithm>
#include <set>
#include <functional>

using namespace std;

int main(int argc, char const* argv[]) {
    set<int> collSet{2,3,1,0,5};
    transform(collSet.begin(), collSet.end(), collSet.begin(), negate<int>());
    return 0;
}

错误提示:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:1948:19: error: cannot assign to return value because function 'operator*' returns a const value
        *__result = __op(*__first);
        ~~~~~~~~~ ^
transformset.cpp:9:5: note: in instantiation of function template specialization 'std::__1::transform<std::__1::__tree_const_iterator<int, std::__1::__tree_node<int, void *> *, long>, std::__1::__tree_const_iterator<int, std::__1::__tree_node<int, void
      *> *, long>, std::__1::negate<int> >' requested here
    transform(collSet.begin(), collSet.end(), collSet.begin(), negate<int>());
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tree:921:31: note: function 'operator*' which returns const-qualified type 'std::__1::__tree_const_iterator<int, std::__1::__tree_node<int, void
      *> *, long>::reference' (aka 'const int &') declared here
    _LIBCPP_INLINE_VISIBILITY reference operator*() const

在书上和网上看到很多这样的写法,但是本地运行报错,求大佬指点迷津。

  • 写回答

1条回答 默认 最新

  • 胡撸娃哈哈 2021-04-27 11:31
    关注

    我看了下源码,返回的iterator不是const的

    //Set源码
     _LIBCPP_INLINE_VISIBILITY
              iterator begin() _NOEXCEPT       {return __tree_.begin();}
        _LIBCPP_INLINE_VISIBILITY
        const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
        _LIBCPP_INLINE_VISIBILITY
              iterator end() _NOEXCEPT         {return __tree_.end();}
        _LIBCPP_INLINE_VISIBILITY
        const_iterator end()   const _NOEXCEPT {return __tree_.end();}
    

    问题在于,transform中会调用*first

    template <class _InputIterator, class _OutputIterator, class _UnaryOperation>
    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
    _OutputIterator
    transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
    {
        for (; __first != __last; ++__first, (void) ++__result)
            *__result = __op(*__first);//这里这里
        return __result;
    }

    而在_tree中,*操作符重载有const限制,如下:

    
    _LIBCPP_INLINE_VISIBILITY reference operator*() const // 这里这里
        {return __get_np()->__value_;}
    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
        {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
    

    应该是这个原因。

    其实我比较纳闷,网上那些人是怎么通过编译的,可能是C++版本不一样?我用的11(狗头)

    评论

报告相同问题?