C++ 通用条款7.2 c++;17 constexpr
我尝试只为理解constexpr实现constexpr堆栈。 我不理解以下代码中的编译错误:C++ 通用条款7.2 c++;17 constexpr,c++,gcc,compiler-errors,c++17,C++,Gcc,Compiler Errors,C++17,我尝试只为理解constexpr实现constexpr堆栈。 我不理解以下代码中的编译错误: 如果我正确理解constexpr并不意味着const 它编译包含push调用的init list constexpr构造函数 它编译执行pop的lambda spop 我错过了什么 g++prog.cc-Wall-Wextra-I/opt/wandbox/boost-1.65.0/gcc-7.2.0/include-std=gnu++1z #包括 #包括 #包括 命名空间ds{ 模板 类数组\堆栈最终
g++prog.cc-Wall-Wextra-I/opt/wandbox/boost-1.65.0/gcc-7.2.0/include-std=gnu++1z
#包括
#包括
#包括
命名空间ds{
模板
类数组\堆栈最终{
公众:
使用值_type=T;
使用引用=值\类型&;
使用const_reference=value_type const&;
使用size\u type=std::size\u t;
constexpr bool empty()const
{
返回项=大小\类型{0};
}
constexpr bool full()常量
{
返回顶部项目=N;
}
constexpr size_type size()const
{
退货项目;;
}
constexpr参考顶部()&
{
if(空())
抛出std::logic_错误{“正在空堆栈上尝试top()”;
返回数组_uu[top_item_uu-1];
}
constexpr const_引用top()const&
{
if(空())
抛出std::logic_错误{“正在空堆栈上尝试top()”;
返回数组_uu[top_item_uu-1];
}
constexpr void push(值\类型const&value)
{
if(full())
抛出std::logic_错误{“正在尝试在整个堆栈上推送()”;
数组_uu[top_item_u]=值;
顶项;
项目++;
}
constexpr void push(值\类型和值)
{
if(full())
抛出std::logic_错误{“正在尝试在整个堆栈上推送()”;
数组_uu[top_item_u]=std::move(值);
顶项;
项目++;
}
constexpr void pop()
{
if(空())
抛出std::logic_错误{“正在空堆栈上尝试pop()”;
第一项;
项目u--;
}
constexpr void clear()
{
项目=大小\类型{0};
顶部项目=大小类型{0};
}
constexpr数组_堆栈()
:items{size\u type{0},top{item{size\u type{0},array{
{}
constexpr数组\u堆栈(std::初始值设定项\u列表值):数组\u堆栈()
{
用于(自动常量和v:值)
推(v);
}
constexpr数组堆栈(数组堆栈const&rhs):数组堆栈()
{
数组=rhs.array;
项目=rhs.items;
顶部项目=rhs.top项目;
}
constexpr数组栈(数组栈和rhs)
:items{rhs.items},top{rhs.top{u item},数组{std::move(rhs.array)}
{
rhs.items u=大小u类型{0};
rhs.top_item_u=size_type{0};
}
constexpr数组\堆栈和运算符=(数组\堆栈rhs)
{
数组=标准::移动(rhs.array);
项目=标准::移动(rhs.items);
顶部项目=标准::移动(rhs.顶部项目);
归还*这个;
}
~array_stack()=默认值;
无效交换(数组、堆栈和rhs)无异常(std::不可交换)
{
使用std::swap;
交换(项目uu,右侧项目uu);
交换(顶部项目,右侧顶部项目);
交换(数组,右数组);
}
私人:
尺寸\类型项目\尺寸;
尺寸\u类型顶部\u项目\uu;
std::数组;
};
模板
无效交换(数组\堆栈和lhs、数组\堆栈和rhs)noexcept(noexcept(lhs.swap(rhs)))
{
左舵互换(右舵);
}
}
constexpr bool f()
{
constepr ds::数组_堆栈数据堆栈{0,1,2,3,4,5,6,7,8,9};
constepr ds::数组_堆栈dstack2{dstack};
constexpr auto spop=[](auto s){s.pop();返回s.size();};
静态断言(dstack.size()=10);
静态断言(!dstack.empty());
静态断言(dstack.full());
静态断言(dstack.top()==9);
静态断言(dstack2.size()=10);
静态断言(spop(dstack)==9);
dstack2.pop();
返回true;
}
int main()
{
constexpr ds::数组_堆栈cstack;
静态断言(cstack.size()==0);
静态断言(cstack.empty());
静态断言(!cstack.full());
静态断言(f());
返回0;
}
我得到这个错误(我理解它的意思,但为什么?)
prog.cc:在函数“constexpr bool f()”中:
prog.cc:147:15:错误:将“const ds::array_stack”作为“this”参数传递将丢弃限定符[-fppermissive]
dstack2.pop();
^
prog.cc:66:24:注意:在调用“constexpr void ds::array_stack::pop()[with T=int;long unsigned int N=10]时”
constexpr void pop()
^~~
constexpr
。这就是为什么dstack2.pop()
格式不正确的原因-这是非常无聊的C++03原因,您正在调用const
对象上的非const
成员函数
删除dstack2.pop()
行后,所有内容都将编译
const
(否则您无法构造它)。在lambda的情况下,参数不是const
——它只是auto
constexpr
。这就是为什么dstack2.pop()
格式不正确的原因-这是非常无聊的C++03原因,您正在调用const
对象上的非const
成员函数
一旦删除dstack2.pop()g++ prog.cc -Wall -Wextra -I/opt/wandbox/boost-1.65.0/gcc-7.2.0/include -std=gnu++1z
#include <array>
#include <stdexcept>
#include <type_traits>
namespace ds {
template <typename T, std::size_t N>
class array_stack final {
public:
using value_type = T;
using reference = value_type&;
using const_reference = value_type const&;
using size_type = std::size_t;
constexpr bool empty () const
{
return items_ == size_type{0};
}
constexpr bool full () const
{
return top_item_ == N;
}
constexpr size_type size () const
{
return items_;
}
constexpr reference top () &
{
if (empty())
throw std::logic_error{"Attempting top() on empty stack"};
return array_[top_item_ - 1];
}
constexpr const_reference top () const&
{
if (empty())
throw std::logic_error{"Attempting top() on empty stack"};
return array_[top_item_ - 1];
}
constexpr void push (value_type const& value)
{
if (full())
throw std::logic_error{"Attempting push() on full stack"};
array_[top_item_] = value;
top_item_++;
items_++;
}
constexpr void push (value_type&& value)
{
if (full())
throw std::logic_error{"Attempting push() on full stack"};
array_[top_item_] = std::move(value);
top_item_++;
items_++;
}
constexpr void pop ()
{
if (empty())
throw std::logic_error{"Attempting pop() on empty stack"};
top_item_--;
items_--;
}
constexpr void clear ()
{
items_ = size_type{0};
top_item_ = size_type{0};
}
constexpr array_stack ()
: items_{size_type{0}}, top_item_{size_type{0}}, array_{}
{}
constexpr array_stack (std::initializer_list<value_type> values) : array_stack ()
{
for (auto const& v : values)
push(v);
}
constexpr array_stack (array_stack const& rhs) : array_stack ()
{
array_ = rhs.array_;
items_ = rhs.items_;
top_item_ = rhs.top_item_;
}
constexpr array_stack (array_stack&& rhs)
: items_ {rhs.items_}, top_item_ {rhs.top_item_}, array_ {std::move(rhs.array_)}
{
rhs.items_ = size_type{0};
rhs.top_item_ = size_type{0};
}
constexpr array_stack& operator= (array_stack rhs)
{
array_ = std::move(rhs.array_);
items_ = std::move(rhs.items_);
top_item_ = std::move(rhs.top_item_);
return *this;
}
~array_stack () = default;
void swap (array_stack& rhs) noexcept(std::is_nothrow_swappable_v<value_type>)
{
using std::swap;
swap(items_, rhs.items_);
swap(top_item_, rhs.top_item_);
swap(array_, rhs.array_);
}
private:
size_type items_;
size_type top_item_;
std::array<value_type, N> array_;
};
template <typename T, std::size_t N>
void swap (array_stack<T, N>& lhs, array_stack<T, N>& rhs) noexcept(noexcept(lhs.swap(rhs)))
{
lhs.swap(rhs);
}
}
constexpr bool f()
{
constexpr ds::array_stack <int, 10> dstack{0,1,2,3,4,5,6,7,8,9};
constexpr ds::array_stack <int, 10> dstack2{dstack};
constexpr auto spop =[](auto s){ s.pop(); return s.size(); };
static_assert(dstack.size() == 10);
static_assert(!dstack.empty());
static_assert(dstack.full());
static_assert(dstack.top() == 9);
static_assert(dstack2.size() == 10);
static_assert(spop(dstack) == 9);
dstack2.pop();
return true;
}
int main()
{
constexpr ds::array_stack <int, 10> cstack;
static_assert(cstack.size() == 0);
static_assert(cstack.empty());
static_assert(!cstack.full());
static_assert(f());
return 0;
}
prog.cc: In function 'constexpr bool f()':
prog.cc:147:15: error: passing 'const ds::array_stack<int, 10>' as 'this' argument discards qualifiers [-fpermissive]
dstack2.pop();
^
prog.cc:66:24: note: in call to 'constexpr void ds::array_stack<T, N>::pop() [with T = int; long unsigned int N = 10]'
constexpr void pop ()
^~~