微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

取std :: vector <bool> :: atsize_t结果的地址,如何为C ++ 11修复?

如何解决取std :: vector <bool> :: atsize_t结果的地址,如何为C ++ 11修复?

功能

template<typename T>
void f(int stack,std::vector<T> *vec,void (*readItemFunc)(int,T*))
{
    // omitted irrelevant code

    for(size_t i = 0; i < sz; i++)
    {
        readItemFunc(stack,&vec->at(i));
    }
}

由于std::vector<bool>的专业性而无法编译。 Clang ++报告此编译错误

没有从__bit_iterator<std::__1::vector<bool,std::__1::allocator<bool> >,false>bool *的转换

在C ++ 17中,我可以这样做:

template<typename T>
void f(int stack,T*))
{
    // omitted irrelevant code

    for(size_t i = 0; i < sz; i++)
    {
        if constexpr(std::is_same<T,bool>::value)
        {
            T v;
            readItemFunc(stack,&v);
            (*vec)[i] = v;
        }
        else
        {
            readItemFunc(stack,&vec->at(i));
        }
    }
}

但这是唯一需要C ++ 17的行,而项目的其余部分支持C ++ 11,因此我会尽量坚持使用C ++ 11,直到有意义为止。

考虑到“省略的无关代码”相当长,并且取决于T,因此,f()专用于bool会涉及很多代码重复。

我可以通过什么其他方式为C ++ 11解决此问题?

解决方法

您基本上可以将T v; expression_that_modifies(&v); vec->at(i) = v;包装在一个类中,其中std::vector<bool>::reference是在表达式的求值完成时调用的析构函数中分配的。

例如,

template<typename T>
T& wrap_vector_bool_reference(T& p) noexcept {
    return p;
}

struct vector_bool_wrapper {
    std::vector<bool>::reference ref;
    bool real_bool;
    vector_bool_wrapper(std::vector<bool>::reference r) noexcept : ref(r),real_bool(r) {}

    operator bool&() noexcept {
        return real_bool;
    }
    bool* operator&() noexcept {
        return &real_bool;
    }
    ~vector_bool_wrapper() {
        ref = real_bool;
    }
};

inline vector_bool_wrapper wrap_vector_bool_reference(std::vector<bool>::reference ref) noexcept {
    return vector_bool_wrapper(ref);
}


template<typename T>
void f(int stack,std::vector<T> *vec,void (*readItemFunc)(int,T*))
{
    // omitted irrelevant code

    for(size_t i = 0; i < sz; i++)
    {
        // No wrapper is applied if `T` isn't `bool`
        readItemFunc(stack,&wrap_vector_bool_reference(vec->at(i)));
    }
}

如果您有多个语句,则可以使用一个额外的变量:

{
    auto&& i = wrap_vector_bool_reference(vec->at(i));
    // i is `T&` normally,but `vector_bool_wrapper&&` if `T` is `bool`.

    // Can cast `i` to `T&`,like
    T& ref = i;
    T* ptr = &i;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。