c++17 相关问题

C ++ 17是2017年批准的C ++标准的名称。它基于以前的C ++ 14标准,改进了核心语言和标准库,并添加了一些新的语言功能。

如何在C++17中获取shared_ptr的原始指针?

我正在使用 C 库,并且希望将对象指针隐藏到共享指针。假设 C 库有... T* 创建对象(); 无效 DoStuff(T*); 无效销毁对象(T*); 那我可以做... 标准::

回答 1 投票 0

嵌套匿名命名空间

以下几行是等效的(从 c++17 开始): 命名空间 A { 命名空间 B {} } 命名空间 A::B {} 下面的行是否有合格的等效项? 命名空间 A { 命名空间 {} } 谢谢你

回答 2 投票 0

在c++中,内存将分配给全局函数,并且全局函数的地址会在运行时改变还是不会改变?

//绑定示例 #include // std::cout #include // std::bind // 一个函数: (也适用于函数对象: std::divides my_divide;) 双

回答 1 投票 0

无法创建多个 constexpr getter

我有一个包装多个 std::sets 数据的结构。我想访问要在编译时计算的集合。为此,我创建了一个模板 constexpr getter 方法来返回请求的 se...

回答 1 投票 0

两个相同的构造函数,但编译器选择模板化的构造函数

我正在尝试在 C++ 中实现一个列表容器,但编译器选择错误的重载时遇到问题。 重载如下: 列表(size_type count, const T& value); 模板<

回答 2 投票 0

两种相同的方法,但编译器选择模板化的方法

我正在尝试在 C++ 中实现一个列表容器,但编译器选择错误的重载时遇到问题。 重载如下: 列表(size_type count, const T& value); 模板<

回答 1 投票 0

SFINAE 用于检查涉及复制赋值的复杂表达式的有效性

考虑以下类并特别注意Concrete::copy_assign: 结构类型Erased { TypeErased() = 默认值; TypeErased& 运算符=(TypeErased const& other) {...

回答 1 投票 0

为什么 std::vector 的交换函数与所有其他容器的交换函数具有不同的 noexcept 规范?

我注意到 std::vector 容器的交换函数具有与所有其他容器不同的 noexcept 规范。具体来说,如果表达式 std::allocator_tr...

回答 1 投票 0

为什么我的迭代器不能使用 std::copy 算法

为什么 MojVektor 中的 Iterator 类(类似于 std::vector)不能与 std::copy 算法一起使用? MojVektor.hpp #pragma 一次 #包括 #包括 为什么 MojVektor 中的 Iterator 类(类似于 std::vector)不能与 std::copy 算法一起使用? MojVektor.hpp #pragma once #include <iostream> #include <initializer_list> #include <algorithm> #include <Iterator> template <typename T> class MojVektor { private: size_t capacity_; size_t size_; T* arr_; void realoc() { capacity_ *= 2; T* tempArr = arr_; arr_ = new T[capacity_]; std::copy(tempArr, tempArr + size_, arr_); delete[] tempArr; return; } public: class Iterator; MojVektor() : capacity_{ 10 }, size_{ 0 }, arr_{ new T[capacity_] } {}; MojVektor(const std::initializer_list<T>& list) : capacity_{ list.size() }, size_{ list.size() }, arr_{ new T[capacity_] } { std::copy(list.begin(), list.end(), arr_); return; } MojVektor(const MojVektor& second) : capacity_{ second.capacity_ }, size_{ second.size_ }, arr_{ new T[capacity_] } { std::copy(second.arr_, second.arr_ + size_, arr_); return; } MojVektor& operator=(const MojVektor& second) { capacity_ = second.capacity_; size_ = second.size_; arr_ = new T[capacity_]; std::copy(second.arr_, second.arr_ + size_, arr_); return *this; } MojVektor(MojVektor&& second) : capacity_{ std::move(second.capacity_) }, size_{ std::move(second.size_) }, arr_{ std::move(second.arr_) } { second.capacity_ = 0; second.size_ = 0; second.arr_ = nullptr; return; } MojVektor& operator=(MojVektor&& second) { capacity_ = std::move(second.capacity_); size_ = std::move(second.size_); arr_ = std::move(second.arr_); second.capacity_ = 0; second.size_ = 0; second.arr_ = nullptr; return *this; } ~MojVektor() { delete[] arr_; size_ = 0; capacity_ = 0; return; } MojVektor& push_back(const T& e) { if (arr_ == nullptr) { capacity_ = 10; arr_ = new T[capacity_]; } if (size_ >= capacity_) { realoc(); } arr_[size_] = e; ++size_; return *this; } MojVektor& push_front(const T& e) { if (arr_ == nullptr) { capacity_ = 10; arr_ = new T[capacity_]; } if (size_ >= capacity_) { realoc(); } for (T* endIndex = arr_ + size_ - 1; endIndex >= arr_; --endIndex) { *(endIndex + 1) = std::move(*(endIndex)); } *(arr_) = e; ++size_; return *this; } MojVektor& push_back(T&& e) { if (arr_ == nullptr) { capacity_ = 10; arr_ = new T[capacity_]; } if (size_ >= capacity_) { realoc(); } arr_[size_] = std::move(e); ++size_; return *this; } MojVektor& push_front(T&& e) { if (arr_ == nullptr) { capacity_ = 10; arr_ = new T[capacity_]; } if (size_ >= capacity_) { realoc(); } for (T* endIndex = arr_ + size_ - 1; endIndex >= arr_; --endIndex) { *(endIndex + 1) = std::move(*(endIndex)); } *(arr_) = std::move(e); ++size_; return *this; } size_t size() const { return size_; } T& at(size_t index) const { if (index < 0 || index > size_ - 1) { throw std::out_of_range("Index out of range!"); } return *(arr_ + index); } T& operator[](size_t index) const { return *(arr_ + index); } void clear() { capacity_ = 0; size_ = 0; delete[] arr_; arr_ = nullptr; return; } void resize(size_t newSize, const T& difference_value) { if (newSize < size_) { size_ = newSize; } else if (newSize > size_) { T* tempArr = arr_; capacity_ = newSize; arr_ = new T[capacity_]; std::copy(tempArr, tempArr + size_, arr_); while (size_ < newSize) { arr_[size_] = difference_value; ++size_; } } return; } MojVektor& pop_back() { if (size_ == 0) { throw std::out_of_range("Vector is empty!"); } --size_; return *this; } MojVektor& pop_front() { if (size_ == 0) { throw std::out_of_range("Vector is empty!"); } for (T* beginIndex = arr_; beginIndex < arr_ + size_; ++beginIndex) { *(beginIndex) = std::move(*(beginIndex + 1)); } --size_; return *this; } T& back() const { if (size_ == 0) { throw std::out_of_range("Vector is empty!"); } return arr_[size_ - 1]; } T& front() const { if (size_ == 0) { throw std::out_of_range("Vector is empty!"); } return *arr_; } bool empty() const { return size_ == 0; } size_t capacity() const { return capacity_; } bool operator==(const MojVektor& second) const { if (size_ != second.size_) { return false; } for (size_t i = 0; i < size_; ++i) { if ((this->operator[](i)) != second[i]) { return false; } } return true; } bool operator!=(const MojVektor& second) const { return !(this->operator==(second)); } bool full() const { return size_ == capacity_; } MojVektor subvector(Iterator beginIt, Iterator endIt) const { if (beginIt < begin() || endIt > end()) { throw std::out_of_range("Iterators out of range!"); } MojVektor v; while (beginIt != endIt) { v.push_back(*beginIt); ++beginIt; } return v; } Iterator begin() const { return Iterator(arr_); } Iterator end() const { return Iterator(arr_ + size_); } Iterator find(const T& value) const { Iterator it = begin(); while (it != end()) { if (*(it) == value) { return it; } ++it; } return it; } Iterator erase(Iterator pos) { if (pos < begin() || pos > end()) { throw std::out_of_range("Iterator out of range!"); } if (pos == end()) { return end(); } Iterator it{ pos }; while (it != end()) { *(it) = std::move(*(it + 1)); ++it; } --size_; return pos; } Iterator insert(Iterator pos, const T& e) { size_t index = pos - begin(); if (index < 0 || index >= size_) { throw std::out_of_range("Iterator out of range!"); } if (size_ >= capacity_) { realoc(); } if (index == 0) { push_front(e); } else { for (size_t i = size_; i >= index; --i) { *(arr_ + i + 1) = std::move(*(arr_ + i)); } arr_[index] = e; ++size_; } return Iterator{ arr_ + index }; } Iterator insert(Iterator pos, T&& e) { size_t index = pos - begin(); if (index < 0 || index >= size_) { throw std::out_of_range("Iterator out of range!"); } if (size_ >= capacity_) { realoc(); } if (index == 0) { push_front(std::move(e)); } else { for (size_t i = size_; i >= index; --i) { *(arr_ + i + 1) = std::move(*(arr_ + i)); } arr_[index] = std::move(e); ++size_; } return Iterator{ arr_ + index }; } Iterator rbegin() const { return end() - 1; } Iterator rend() const { return begin() - 1; } Iterator erase(Iterator beginIt, Iterator endIt) { size_t beginIndex = beginIt - begin(); size_t endIndex = endIt - begin(); if (beginIndex > endIndex || beginIndex < 0 || endIndex > size_ || beginIndex > size_) { throw std::out_of_range("Iterators out of range!"); } for (size_t i = beginIndex; i < endIndex; ++i) { arr_[i] = std::move(arr_[endIndex - beginIndex + i]); } size_ -= (endIndex - beginIndex); return Iterator{ arr_ + beginIndex }; } void rotate() { for (size_t beginIndex = 0, endIndex = size_ - 1; beginIndex < endIndex; ++beginIndex, --endIndex) { std::swap(arr_[beginIndex], arr_[endIndex]); } return; } void rotate(Iterator beginIt, Iterator endIt) { size_t beginIndex = beginIt - Iterator(arr_); size_t endIndex = (endIt - Iterator(arr_)) - 1; if (beginIndex > endIndex || beginIndex < 0 || endIndex > size_ || beginIndex > size_) { throw std::out_of_range("Iterators out of range!"); } while (beginIndex < endIndex) { std::swap(arr_[beginIndex], arr_[endIndex]); ++beginIndex; --endIndex; } return; } T* data() { return arr_; } }; template <typename T> std::ostream& operator<<(std::ostream& outputStream, const MojVektor<T>& container) { const size_t size = container.size(); outputStream << "{"; for (size_t i = 0; i < size; ++i) { outputStream << container[i]; if (i + 1 < size) { outputStream << ", "; } } outputStream << "}"; return outputStream; } template <typename T> class MojVektor<T>::Iterator : public std::iterator<std::random_access_iterator_tag, T> { private: T* ptr_; public: Iterator() : ptr_{ nullptr } {}; Iterator(T* ptr) : ptr_{ ptr } {}; Iterator(T& e) : ptr_{ &e } {}; Iterator(const Iterator& second) : ptr_{ second.ptr_ } {}; Iterator(Iterator&& second) : ptr_(std::move(second.ptr_)) { second.ptr_ = nullptr; return; } Iterator& operator=(const Iterator& second) { ptr_ = second.ptr_; return *this; } Iterator& operator=(Iterator&& second) { ptr_ = std::move(second.ptr_); second.ptr_ = nullptr; return *this; } T& operator*() { return *ptr_; } Iterator& operator++() { ++ptr_; return *this; } Iterator operator++(int) { Iterator returnValue{ ptr_ }; ++ptr_; return returnValue; } Iterator& operator--() { --ptr_; return *this; } Iterator operator--(int) { Iterator returnValue{ ptr_ }; --ptr_; return returnValue; } Iterator& operator+=(size_t n) { ptr_ += n; return *this; } Iterator& operator-=(size_t n) { ptr_ -= n; return *this; } Iterator operator+(size_t n) const { return Iterator(ptr_ + n); } Iterator operator-(size_t n) const { return Iterator(ptr_ - n); } T* operator->() { return ptr_; } size_t operator-(const Iterator& second) const { return ptr_ - second.ptr_; } T& operator[](size_t index) const { return *(ptr_ + index); } bool operator==(const Iterator& second) const { return ptr_ == second.ptr_; } bool operator!=(const Iterator& second) const { return !(this->operator==(second)); } bool operator<(const Iterator& second) const { return ptr_ < second.ptr_; } bool operator>(const Iterator& second) const { return ptr_ > second.ptr_; } bool operator<=(const Iterator& second) const { return ptr_ <= second.ptr_; } bool operator>=(const Iterator& second) const { return ptr_ >= second.ptr_; } }; 主.cpp #include <iostream> #include "MojVektor.hpp" #include <algorithm> int main() { MojVektor<int> a{1, 2, 3}; MojVektor<int> b; std::copy(a.begin(), a.end(), b.begin()); std::cout << a << std::endl; std::cout << b << std::endl; return 0; } 我尝试手动设置 iterator_tag、value_type 等,使用 using、using 和继承、typedef 和 typedef 和继承。我还查看了之前提出的一些问题,但它们与列表和插入器相关,也在答案中添加了我的代码中已经存在的继承。 主要是两个问题: std::iterator 类已被弃用,因此在这里建立依赖关系不是一个好主意。 您的 Iterator 类缺少必要的类型别名。 更正这两项后,您的代码将可以编译: template <typename T> class MojVektor<T>::Iterator { private: T* ptr_; public: using iterator_category = std::random_access_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; using reference = T&; // .... };

回答 1 投票 0

如何在 VSCode C++ 扩展中启用 C++17 标准

我想在 VS Code 中将 c++11 切换为 c++17。我尝试按照说明进行操作,但没有成功。 任务.json “版本”:“2.0.0”, “任务”: [ { “……

回答 3 投票 0

printf() a std::string_view 的正确方法?

我是 C++17 和 std::string_view 的新手。 我了解到它们不是空终止的,必须小心处理。 这是 printf() 的正确方法吗? #包括 #包括<...

回答 4 投票 0

理解 C++ 中的 `this` 指针、`return *this` 和引用

我目前正在学习 C++ 中的面向对象编程,我正在尝试理解 this 指针、return *this 和引用的使用的概念。我遇到过一个

回答 1 投票 0

在c++中循环命名空间中的所有函数

我的目标是迭代命名空间的所有函数,直到函数返回我有效的策略(枚举)。每个函数可以采用不同的参数。 枚举类策略类型 { 策略1、

回答 2 投票 0

额外移动构造函数调用的说明

我将直接转到代码并解释我在这里想要理解的内容。 MyInt 类 { unique_ptr ptr; 民众: MyInt(int val) { 计算<...

回答 1 投票 0

模板参数的 HomoValueList 不起作用

问题是我在 Nicolai M. Josuttis 所著的《C++17 Complete Guide》一书中遇到了一段代码,第 122 页。该代码片段对我不起作用。我想知道为什么。 模板 问题是我在 Nicolai M. Josuttis 的一本名为 C++17 Complete Guide 的书中遇到了一段代码,第 122 页。该代码片段对我不起作用。我想知道为什么。 template<auto V1, decltype(V1)... VS> class HomoValueList { }; 作者声称这样的声明应该禁止非同构模板参数。但实际上我不能产生错误: int main() { HomoValueList<1, 'a', true> vals4; // Must be an error according to the author but not for me. return 0; } 这段代码是因为隐式转换而编译的,所以这本书是错误的。 我想知道自 C++17 标准发布以来是否发生了一些变化,因为作者声称必须禁止该行。 我不这么认为。即使在 C++17 模式下,最新的 Clang、GCC 和 MSVC 都接受此代码。 这是一个可行的 C++20 替代方案:(感谢 @PatrickRoberts) template <auto V1, auto ...VS> requires (std::is_same_v<decltype(V1), decltype(VS)> && ...) class HomoValueList {}; C++20 之前的版本,您可以使用 static_assert,但请注意,它不适合 SFINAE。 template<auto V1, auto ...VS> class HomoValueList { static_assert((std::is_same_v<decltype(V1), decltype(VS)> && ...)); };

回答 1 投票 0

当派生类仅重写所有方法的子集时,为什么会出现 C++ 编译错误,所有方法都具有相同的名称但不同的签名(重载)

简单地说,您有一个接口基类 A,它提供了一个多态 method(),一个派生类 B,它实现了其中一些 method() 的细节。然后一些外部函数调用这些,co...

回答 1 投票 0

如何泛化任何可变参数模板类型的模板专业化?

我有以下类型函数来计算某个类型 T 是否是元组中类型列表的一部分: 模板 结构体IsInTuple; 模板 我有以下类型函数来计算某种类型T是否是元组中类型列表的一部分: template<typename T, typename Tuple> struct IsInTuple; template<typename T, typename ...Ts> struct IsInTuple<T, std::tuple<Ts...>> { static constexpr bool value = std::disjunction_v<std::is_same<T, Ts>...>; }; 我的问题是,是否可以将此函数推广到任何采用可变参数类型列表的可变参数模板类型,以便它不仅适用于元组,而且还适用于变体? 是否可以将此函数推广到任何采用可变参数类型列表的可变参数模板类型,以便它不仅适用于 std::tuples,而且还适用于 std::variants? 是的,可以。只需使用模板模板参数来概括情况即可。 template<typename T, typename Class> struct IsInTypeList; template<template<typename...Ts> class Class, typename T, typename ...Ts> struct IsInTypeList<T, Class<Ts...>> { static constexpr bool value = (std::is_same_v<T, Ts> || ...); }; // Example usage static_assert(IsInTypeList<int, std::tuple<int, float, double>>::value, "int is in the tuple"); static_assert(!IsInTypeList<char, std::tuple<int, float, double>>::value, "char is not in the tuple"); static_assert(!IsInTypeList<char, std::variant<int, float, double>>::value, "char is not in the tuple");

回答 1 投票 0

当存在移动和复制构造函数时,C++ 默认构造函数不会通过“using”继承

A级{ 民众: A(){}; }; B 类:公共 A{ 民众: 使用 A::A; B(const B&) = 默认值; B(B&&)=默认值; }; 乙b; 编译器 (g++ (5.4.0-6ubuntu1) /...

回答 3 投票 0

指定从 std::variant 获取类型的更简洁方法?

我有可以简化为的代码 std::variant v[2] = foo(); int a = std::get(v[0]); 浮点数 b = std::get(v[1]); 显然这可以...

回答 3 投票 0

如果类型包包含特定类型,如何仅向类添加方法?

我正在尝试创建一个可以包含类型包的类。 // 包.hpp 模板 班级包决赛 { Pack(const std::tuple items) : items_(std::move(item...

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.