Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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++ 通用条款7.2 c++;17 constexpr_C++_Gcc_Compiler Errors_C++17 - Fatal编程技术网

C++ 通用条款7.2 c++;17 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{ 模板 类数组\堆栈最终

我尝试只为理解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{
    模板
    类数组\堆栈最终{
    公众:
    使用值_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并不意味着const
  • 否。声明的对象
    constexpr
    。这就是为什么
    dstack2.pop()
    格式不正确的原因-这是非常无聊的C++03原因,您正在调用
    const
    对象上的非
    const
    成员函数

    删除
    dstack2.pop()
    行后,所有内容都将编译

  • 它编译包含push调用的init list constexpr构造函数
  • 它编译执行pop的lambda spop
  • 在这两种情况下,您都可以修改对象。在第一种情况下,您仍然在构造函数中-因此修改是可以的,对象在构造过程中永远不会
    const
    (否则您无法构造它)。在lambda的情况下,参数不是
    const
    ——它只是
    auto

  • 如果我正确理解constexpr并不意味着const
  • 否。声明的对象
    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 ()
                            ^~~