Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ GCC7在同一类中推断常量修饰符的存在_C++_This_Constants_C++17_Decltype - Fatal编程技术网

C++ GCC7在同一类中推断常量修饰符的存在

C++ GCC7在同一类中推断常量修饰符的存在,c++,this,constants,c++17,decltype,C++,This,Constants,C++17,Decltype,我最初想在一个类中推断它是使用常量修饰符声明还是不使用常量修饰符声明的。正如许多人指出的,声明为const的是变量本身(而不是类)。谢谢你说清楚。这个错误消息现在对我来说完全有意义了。因此,这更多的是一个设计问题 我想要的是一个结构,它的行为类似于随机访问容器,并提供一些函数,如迭代器begin(){…},常量迭代器cbegin(){…},尤其是值类型运算符[](size\u type idx){…}等等。我想提供尽可能多的函数,不管实例是否为const。因此,实际上A{};a、 begin()

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

我想要的是一个结构,它的行为类似于随机访问容器,并提供一些函数,如
迭代器begin(){…}
常量迭代器cbegin(){…}
,尤其是
值类型运算符[](size\u type idx){…}
等等。我想提供尽可能多的函数,不管实例是否为const。因此,实际上
A{};a、 begin()
将返回值类型为
a
a.cbegin()
常量引用的非常量引用。而对于
A常数ac{}
ac.begin()
ac.cbegin()
应具有相同的常量引用类型。但这些用例可能没有意义。 我可以限制使用只有非常量
a
与非常量迭代器结合使用的情况(即允许
a.begin()
,但不允许
a.cbegin()
),以及只有常量迭代器才能调用
ac
(即
ac.cbegin()
,但不允许
ac.begin()
)。这有意义吗

这种奇怪尝试背后的原因是,在我的实现中,不存在一个底层容器,而是两个辅助容器:位向量和压缩序列。根据位向量的内容,我返回压缩序列的特殊符号或字母(参见扩展代码示例)。 此外,我不使用std::迭代器,而是使用自己的实现。注意:
(*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;
}
#包括
#包括
#包括
#包括
#包括
模板
结构我的迭代器
{
私人:
使用reference=std::conditional\u t;
使用size\u type=typename容器\u t::size\u type;
尺寸\类型偏移=0;
typename std::add_pointer_t host{nullptr};
公众:
我的迭代器(容器和主机,大小和类型偏移量):主机{&host},偏移量{offset}{
引用运算符[](typename容器:大小类型常量idx)
{
返回(*主机)[idx+偏移];
}
};
模板
结构A//实现容器概念的一些功能
{
使用const\u reference=typename sequence\u t::const\u reference;
使用reference=typename序列\ u t::value \ u type;
使用迭代器=我的迭代器;
使用常量迭代器=我的迭代器;
使用value\u type=typename序列\u t::value\u type;
使用size\u type=typename序列\u t::size\u type;
//内部用于解析随机访问的数据结构
std::向量位_向量{1,0,1,0,0};
向量文本{'h','w'};
constexpr char static const cash='$';
公众:
//提供一些容器函数,如begin、end、cbegin、cend
迭代器begin()
{
返回迭代器{*this,0};
}
常量迭代器cbegin()常量
{
返回常量迭代器{*this,0};
}
// ...
大小类型秩(大小类型idx)常数
{
返回std::累加(bit_vector.begin(),bit_vector.begin()+idx,0);
}
constexpr引用运算符[](大小\类型const idx)const
{
断言(idx
类不是用
const
限定符声明的。这些限定符用于声明变量

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

在任何情况下,我怀疑您假定
std::iterator
是一个迭代器。它不是迭代器。它是一个基类,可以用来避免在编写(自定义)迭代器时重复一些定义。这种混淆可能是它在即将发布的标准版本中被弃用的原因

我想在一个类中推断它是用常量修饰符声明的还是不用常量修饰符声明的

类不是用
const
限定符声明的。这些限定符用于声明变量

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


在任何情况下,我怀疑您假定
std::iterator
是一个迭代器。它不是迭代器。它是一个基类,可用于在编写(自定义)时避免重复一些定义迭代器。这种混乱可能是它在即将到来的标准版本中被弃用的原因。

这种
只存在于成员函数中;这是唯一一种对象意识到自身存在的情况。你想要这样做的原因听起来有点奇怪。如果你解释一下这两者之间的联系,并重载
[]
运算符,您可能会得到帮助以解决实际问题。此外,
A();
是函数返回
a
的声明。你应该改为写
a;
。你不能按照你的建议去做,因为
const
应用于变量,而不是类。但这显然像是一个X-Y问题。你到底想做什么还不清楚,但也许你可以用j得到你需要的东西ust
ret_type1运算符[](size_t);
ret_type2运算符[](size_t)