GCC7 在同一类中推断出常量修饰符的存在
GCC7 Deduce in same class the presence of a const modifier
我最初想在一个类中推断它是用或不带 const 修饰符声明的。正如你们中的许多人指出的那样,是变量本身被声明为 const(而不是类(。感谢您明确这一点。错误消息现在对我来说完全有意义。所以,这更像是一个设计问题。
我想要的是一个结构,它的行为类似于随机访问容器,并提供一些功能,如iterator begin(){...}
,const_iterator cbegin(){...}
,尤其是value_type operator[](size_type idx){...}
等等。我想提供尽可能多的功能,无论实例是否是常量。因此,在实践中,A a{}; a.begin();
将返回A
值类型的非常量引用,并a.cbegin()
常量引用。而对于A const ac{};
ac.begin()
和ac.cbegin()
应该具有相同的常量引用类型。但这些用例可能没有意义。 我可以限制为只有非常量a
与非常量迭代器组合的用例是可调用的(即允许a.begin()
,但不能a.cbegin()
(,并且ac
仅与常量迭代器一起使用(即ac.cbegin()
,但不是ac.begin()
(。这有意义吗?
这种奇怪尝试背后的原因是,在我的实现中,不存在一个底层容器,而是两个辅助容器:一个位向量和一个压缩序列。根据位向量的内容,我返回一个特殊符号或压缩序列的字母(参见扩展代码示例(。 另外,我不使用 std::itrator 而是使用自己的实现。注意(*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
是一个迭代器。它不是迭代器。它是一个基类,可用于在编写(自定义(迭代器时避免重复一些定义。这种混乱可能是它在即将推出的标准版本中将被弃用的原因。
- '尝试解析可变参数模板时无法推断出'T的模板参数
- "auto"推断出 hashtable_policy.h 中的错误类型
- GCC7 在同一类中推断出常量修饰符的存在
- 三元运算符 '?:' 在 4.9.0 之前的 GCC 版本中推断出不正确的类型?
- 为什么"return (str);"推断出与C++中的"return str;"不同的类型?
- 为什么自动说明符从 &指针推断出"顶部和低"级别的常量?
- 为什么编译器不能从返回类型中推断出模板参数?
- std::sort / 适用于测试代码,但无法推断出模板
- 无法从'int'中推断出'Node<T> *'的模板参数
- 完美的转发功能推断出冲突错误
- 从第一类型的第二个非类型参数中推断出第一类
- 是否可以推断出模板功能中的参数类型
- 无法从'std::string'中推断出'const std::reverse_iterator<_RanIt> &'的模板参数
- std::forward 如何推断出"_Ty"的类型?
- 如何允许编译器推断出正确的返回类型以进行模板get函数
- 自动无法推断出正确的返回类型
- 既然C++知道类型,它能推断出点和箭头吗?
- 如何使模板化运算符推断出正确的返回类型
- 有没有办法从基类函数参数中推断出模板参数
- C++错误:推断出参数'T'字符串与常量字符的冲突类型 *