繁体   English   中英

GCC7在同一个类中推断出const修饰符的存在

[英]GCC7 Deduce in same class the presence of a const modifier

我最初想在类中推断是否使用const修饰符声明了它。 正如您中许多人所指出的,变量本身被声明为const(而不是类)。 感谢您澄清这一点。 现在,错误消息对我完全有意义。 因此,这更多是一个设计问题。

我想要的是一个行为类似于随机访问容器的结构,并提供了一些函数,例如iterator begin(){...}const_iterator cbegin(){...} ,尤其是value_type operator[](size_type idx){...}等。 无论实例是否为const,我都希望提供尽可能多的功能。 因此,在实践中A a{}; a.begin(); A a{}; a.begin(); 将返回A值类型的非恒定引用,而a.cbegin()将返回一个const引用。 而对于A const ac{}; ac.begin()ac.cbegin()应该具有相同的常量引用类型。 但是这些用例可能没有意义。 我可能会限制使用,其中只有非const的情况下a与非const迭代器组合是可调用(即允许a.begin()但不a.cbegin()ac只能用常量迭代器(即ac.cbegin() ,而不是ac.begin() )。 这有意义吗?

这种奇怪的尝试背后的原因是,在我的实现中,不存在一个基础容器,而是两个辅助容器:位向量和压缩序列。 根据位向量的内容,我将返回一个特殊符号或压缩序列的字母(请参见扩展代码示例)。 另外,我不使用std :: iterator而是自己的实现。 注意(*host)[idx + offset]返回一个临时值,这可能是为什么我在输出后出现分段错误的原因。

#include <cassert>
#include <iostream>
#include <numeric>
#include <type_traits>
#include <vector>

template<typename container_t>
struct my_iterator
{
private:
    using reference = std::conditional_t<std::is_const<container_t>::value,
                    typename container_t::const_reference,
                    typename container_t::reference>;
    using size_type = typename container_t::size_type;
    size_type offset = 0;
    typename std::add_pointer_t<container_t> host{nullptr};
public:
    my_iterator(container_t & host_, size_type offset_) : host{&host_}, offset{offset_} {}
    reference operator[](typename container_t::size_type const idx)
    {
        return (*host)[idx + offset];
    }
};

template<typename sequence_t>
struct A  // implements some features of the container concept
{
    using const_reference = typename sequence_t::const_reference;
    using reference = typename sequence_t::value_type;
    using iterator = my_iterator<A>;
    using const_iterator = my_iterator<A const>;
    using value_type = typename sequence_t::value_type;
    using size_type = typename sequence_t::size_type;

    // data structures internally used to resolve random access
    std::vector<unsigned int> bit_vector{1,0,1,0,0,0};
    std::vector<char> text{'h', 'w'};
    constexpr char static const cash = '$';

public:
    // provide some container functions, like begin, end, cbegin, cend
    iterator begin()
    {
        return iterator{*this, 0};
    }

    const_iterator cbegin() const
    {
        return const_iterator{*this, 0};
    }
    // ...

    size_type rank(size_type idx) const
    {
        return std::accumulate(bit_vector.begin(),  bit_vector.begin()+idx, 0);
}

constexpr reference operator[](size_type const idx) const
{
    assert(idx < bit_vector.size());
    if (bit_vector[idx])
        return cash;
    return text[idx - rank(idx)];
}
};

int main(){
    /* non const usage */
    A<std::vector<char>> a{};
    auto it_a = a.begin();
    std::cout << it_a[0] << std::endl;
    /*  const usage */
    A<std::vector<char>> const a_const{};
    /* does not compile, because of non matching types */
    auto it_const_a = a_const.begin();
    std::cout << "it_const_a[0] = " << it_const_a[1] << std::endl;
    /* does compile, but gives segmentation fault */
    auto it_const_a2 = a_const.cbegin();
    std::cout << "it_const_a2[0] = " << it_const_a2[1] << std::endl;
}

我想在一个类中推断出是否使用const修饰符声明了它。

没有用const限定符声明 这些限定符用于声明变量

如错误消息所解释的,在非静态成员函数之外没有this 类的成员类型(别名)不依赖于实例,因此不能依赖于实例的常量性。

无论如何,我怀疑您假设std::iterator是迭代器。 不是迭代器。 它是基类,可用于避免在编写(自定义)迭代器时重复一些定义。 这种混乱可能是即将在即将发布的标准版本中弃用的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM