c++17 相关问题

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

为什么 std::array::begin 返回指针而不是迭代器?

我正在尝试构建一个嵌套迭代器模板,并依赖于具有诸如 value_type 之类的各种特征的迭代器。但事实证明,并非所有 STL 类型都返回具有这些特征的迭代器。对于...

回答 2 投票 0

切换 range-v3 的包含标头顺序后编译失败

当我在range-v3 v0.12.0中一起使用views::set_intersection和views::transform时,标题range/v3/view/set_algorithm.hpp和range/v3/view/transform.hpp的顺序很重要。如果是前者

回答 1 投票 0

确保 std::vector 始终对齐以实现最佳 SIMD 执行的方法?

我想要 X 数量的相同大小的 std::vectors,我可以在 for 循环中一起处理它们,该循环以线性方式从开始到结束。例如: 对于 (int i = 0; i <

回答 1 投票 0

在 C++ 中使用 enum 代替 struct 进行标签调度

让我们从标准库中实现 std::unique_lock : struct defer_lock_t { 显式 defer_lock_t() = 默认; }; struct try_to_lock_t { 显式 try_to_lock_t() = 默认; };

回答 2 投票 0

哪些成员函数可以在 C++ 中模板化?

有人问我一个问题 哪些类函数可以在 C++ 中模板化? (构造函数、析构函数、const、静态) 我是否正确理解所有成员函数(析构函数除外)都可以是临时的......

回答 2 投票 0

C++17 可变参数模板折叠

我不明白为什么这不起作用。了解模板和可变表达式折叠的人能否解释正在发生的事情并给出可行的解决方案? #包括 我不明白为什么这不起作用。了解模板和可变表达式折叠的人可以解释正在发生的事情并给出可行的解决方案吗? #include <iostream> #include <string> template <typename... Args> void print(Args... args) { std::string sep = " "; std::string end = "\n"; (std::cout << ... << sep << args) << end; } int main() { print(1, 2, 3); } 它应该打印出每个参数,参数之间有一个空格,末尾有一个换行符。如果您删除 sep <<,但打印时每个参数之间没有空格,它会起作用。 二进制折叠表达式的语法必须是以下之一: (pack op ... op init) (init op ... op pack) 你拥有的是(std::cout << ... << sep << args),它不适合任何一种形式。您需要像 (cout << ... << pack) 这样的东西,这就是删除 sep 有效的原因。 相反,您可以折叠逗号: ((std::cout << sep << args), ...); 或使用递归: template <class A, class... Args> void print(A arg, Args... args) { std::cout << arg; if constexpr (sizeof...(Args) > 0) { std::cout << sep; print(args...); } } 这可以工作,但它会打印一个尾随空格: template <typename... Args> void print(Args... args) { std::string sep = " "; std::string end = "\n"; ((std::cout << args << sep), ...) << end; } 现场魔杖盒示例 在这种情况下,正在执行逗号运算符的折叠,从而导致如下扩展: // (pseudocode) (std::cout << args<0> << sep), (std::cout << args<1> << sep), (std::cout << args<2> << sep), ..., (std::cout << args<N> << sep), 你真正想做的是: std::string sep = " "; std::string end = "\n"; (std::cout << ... << (sep << args)) << end; 因为您希望 (sep << args) 与 std::cout 一起向左折叠。这不起作用,因为 sep << args 不知道它正在流式传输到 std::cout 或根本不知道它正在流式传输; << 仅当左侧是流时才进行流式传输。 简而言之,问题在于sep << args不明白它正在流式传输。 你的另一个问题是 lambda 不够。 我们可以解决这个问题。 template<class F> struct ostreamer_t { F f; friend std::ostream& operator<<(std::ostream& os, ostreamer_t&& self ) { self.f(os); return os; } template<class T> friend auto operator<<(ostreamer_t self, T&& t) { auto f = [g = std::move(self.f), &t](auto&& os)mutable { std::move(g)(os); os << t; }; return ostreamer_t<decltype(f)>{std::move(f)}; } }; struct do_nothing_t { template<class...Args> void operator()(Args&&...)const {} }; const ostreamer_t<do_nothing_t> ostreamer{{}}; template <typename... Args> void print(Args... args) { std::string sep = " "; std::string end = "\n"; (std::cout << ... << (ostreamer << sep << args)) << end; } 活生生的例子。 (我还使用了 sep 的文字来确保我使用右值)。 ostreamer 捕获对它是 << 的事物的引用,然后将它们转储到 << 到 ostream。 整个过程对编译器来说应该是透明的,因此一个好的优化器应该消除涉及的所有内容。 正如其他人所回答的,您正在尝试使用错误的 fold-expression 格式。 您可以通过非常简单的方式使用 lambda 助手来达到您的目的: template <typename... Args> void print(Args&&... args) { std::string sep = " "; std::string end = "\n"; auto streamSep = [&sep](const auto& arg) -> decltype(arg) { std::cout << sep; return arg; }; (std::cout << ... << streamSep(args)) << end; } 这将遵循您编写的代码中预期的行为。但是,如果您想避免第一个参数之前的 sep,您可以使用以下内容: template <typename Arg, typename... Args> void print(Arg&& arg, Args&&... args) { std::string sep = " "; std::string end = "\n"; auto streamSep = [&sep](const auto& arg) -> decltype(arg) { std::cout << sep; return arg; }; std::cout << arg; (std::cout << ... << streamSep(args)) << end; } 另一种方法是下一个: #include <iostream> template<class U, class... T> void printSpaced(const U& u, const T&... args) { using std::cout; using std::endl; ((cout << u) << ... << (cout << ' ', args)) << endl; } 这样你就不会得到前导/尾随空格 用途: printSpaced(1, 2, "Hello", 4.5f); //Output 1 2 Hello 4.5 and no trailing space 你可以尝试这样的事情 template <typename... Args> void print(Args... args) { bool first = true; auto lambda = [&](auto param) { if( !first) std::cout << ','; first= false; return param; }; ((std::cout << lambda(args)), ...); } lambda 确保分隔符仅插入在两个项目之间。 另一方面,如果你不想使用 lambda,你可以重载模板: template<typename T> void print(T item) { std::cout << item; } template<typename T, typename... Args> void print(T item, Args... args) { print(item); std::cout << ','; print(args...); } 如果您不想要前导/尾随sep: template <typename First, typename... Rest> void print(First first, Rest... rest) { std::string sep = " "; std::string end = "\n"; std::cout << first; ((std::cout << sep << rest), ...); std::cout << end; } 您需要制作 std::cout << end; 一条单独的指令来处理具有一个参数的情况。

回答 7 投票 0

用于返回带有布尔结果标志的值的标准模板

当我开始利用 C++17 结构化绑定和 if 运算符 init 语句来进行更优雅的函数结果报告和检查时,我开始执行以下操作(如果符合的话)...

回答 2 投票 0

Clang 在折叠表达式中找不到模板二元运算符

这是我连接元组的二元运算符: 模板 constexpr decltype(auto) 运算符+(const std::tuple &tup1, ...

回答 3 投票 0

折叠表达式和函数名称查找[重复]

我正在学习 C++17 中的折叠表达式。我有以下代码 #包括 #包括 命名空间 io { 模板 std::istream &运算符>>(s...

回答 1 投票 0

模板替换时访问参数包中的索引

我在C++17中有一个模板函数,其中N个第一个参数需要是整数类型,并且应该在模板替换期间检查这一点。 (对于参数来说,模板函数不应该存在...

回答 1 投票 0

在 C++ 中每秒处理 X 个项目的最佳模式是什么?

我有一个 Consumer 类,它应该每秒从队列中删除 n 个项目,但仅此而已: 类消费者{ 消费者(int items_per_sec,存储和存储): 每秒项目数{

回答 1 投票 0

C++ 中哪些类函数可以模板化?

有人问我一个问题 哪些类函数可以在 C++ 中模板化? (构造函数、析构函数、const、静态) 我是否正确理解所有类方法(析构函数除外)都可以是模板......

回答 2 投票 0

如何迭代 std::map 的键?

我正在寻找一种在C ++ 17中迭代映射的键的方法。我现在想到的方法是基于这个问题的答案,该方法如下所示。 对于(自动常量&am...

回答 6 投票 0

C++ 在映射中存储变体类型

在 C++ 中,我想创建一个定义数据管道的函数对列表。 例如,给出这样的事情: 字段名称:“F1” ParserFunction:X ParseX(字符串 s) DestinationFn:无效 Co...

回答 1 投票 0

迭代 std::variant 的映射

我正在尝试使用 C++17 的 std::variant 在映射中存储多种类型的数据。这里的用例是拥有一个我可以迭代的泛型类型控制器的映射(但受 std::variant 约束)

回答 2 投票 0

C++17:传递多个可调用对象及其参数

我想编写一个函数(C++17,如果重要的话),它接受多个可调用对象及其参数并在循环中执行它们。我也想避免任何中间

回答 1 投票 0

std::使用参数包应用 emplace_back

我正在尝试将一个新对象放入模板函数内的容器中。由于模板函数接收一个 std::tuple 以及创建对象所需的参数,因此我使用 std::a...

回答 1 投票 0

为什么重载解析在显式提供模板参数时会选择错误的重载?

我的代码在这里: #包括 #包括 #包括 模板 [[也许未使用]] constexpr auto t1(const std::queue &val...

回答 1 投票 0

为什么这个const类型的模板会出错?

感谢阅读这个问题。 代码在这里。版本 C++17 #包括 #包括 #包括 模板 [[也许未使用]] constexpr 自动 t1(

回答 1 投票 0

std::filesystem::file_time_type 来自 time_t - 如何?

我想从 std::time_t 创建一个 std::filesystem::file_time_type ,但我不知道如何创建。 例子: 时间_t t = 1337; std::filesystem::file_time_type ft = ...; //如何? 理想情况下,我想要...

回答 1 投票 0

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