variadic-templates 相关问题

可变参数模板是采用可变数量参数的模板。

用可变参数替换模板参数列表

有人可以帮助我如何用可变参数模板参数替换模板类型列表,并在类中创建每种类型的唯一指针。 问题是我有课 模板...

回答 1 投票 0

仅进一步传递参数(不单独访问)时模板化和非模板化可变参数函数之间的编译差异

我试图了解 C++ 中模板化与非模板化可变参数函数在编译(特别是编译时间)方面的差异,在特殊情况下...

回答 1 投票 0

可变参数模板类中的通用引用被视为右值引用

我正在尝试创建可变参数模板,它可以获取左值、右值和右值引用作为参数。但似乎 T&& 被视为右值引用并且不接受其他类型...

回答 1 投票 0

如何在 C++ 中将参数包传递给 void 指针?

请考虑以下代码示例: #包括 #包括 模板 类某类 { 民众: std::function 一些...

回答 2 投票 0

如何从 std:::tuple 获取可变参数来解压另一个 std::tuple?

我正在尝试将模板参数列表(枚举类,而不是类型名)转换为 std::tuple 模板参数的相应类型名。我猜我是否能以某种方式给va命名......

回答 1 投票 0

使用 C++17 重载单个特定类型的可变参数函数

我想重载(或专门化)一个可变参数函数,以便重载(或专门化)仅接受特定类型的参数。在 C++20 中我会写: #包括 #inc...

回答 1 投票 0

我可以在类定义内的非类型模板参数包上使用 `enable_if` 吗?

我想在可能固定数量的布尔值上模板化一个类,对它们进行计数,然后使用该数字作为基类的模板参数。像这样的东西 模板 我想在可能固定数量的布尔值上模板化一个类,对它们进行计数,然后使用该数字作为基类的模板参数。像这样的东西 template <int Dimensionality> struct Foo {}; // I want to inherit from this // helpers to compile-time count the true values among bools template <bool B, bool... Args> struct count_true { static constexpr int value = count_true<B>::value + count_true<Args...>::value; }; template <> struct count_true<true> { static constexpr int value = 1; }; template <> struct count_true<false> { static constexpr int value = 0; }; // I want something like this, pseudocode template <bool... Args> struct Bar : public Foo<count_true<Args...>::value> { Bar(bool... args) { // do something with the parameters static_assert(sizeof...(args) <= 1337); } }; 但我找不到办法做到这一点。 似乎有很多与使用 enable_if 作为函数参数包有关的问题,例如 在参数中强制执行单一类型的 C++ 参数包 使用enable_if检查参数包类型 或者在模板类型不用于继承的地方使用,例如 如何启用带有可变模板参数的类? 但在这个特殊情况下,这些都没有帮助。 “伪代码”无法编译,因为 bool... args 不是未扩展的参数包。 我想这样的东西可能会起作用,但事实并非如此,因为参数包必须是最后一个模板参数: template <class... Ts> struct Bar : public Foo<count_true<Ts..., std::enable_if_t<(std::is_same<Ts, bool>::value && ...), bool>>::value> { … } 有办法做到这一点吗?这个问题可能有点困惑,因为我真的不知道我在做什么。模板元编程。 但在这个特殊情况下,这些都没有帮助。 “伪代码” 无法编译,因为 bool... args 不是未扩展的参数 打包。 您可以使用 decltype() 扩展模板参数。此外,count_true可以简单地替换为折叠表达式。 template <bool... Args> struct Bar : public Foo<(Args + ... + 0)> { Bar(decltype(Args)... args) { // do something with the parameters static_assert(sizeof...(args) <= 1337); } };

回答 1 投票 0

使用折叠表达式检查可变参数模板参数是否唯一

给定一个可变参数模板参数包,我想使用内联 constexpr bool 和折叠表达式检查赋予它的所有类型是否都是唯一的。我尝试过这样的事情: 模板 给定一个可变参数模板参数包,我想使用 inline constexpr bool 和 fold 表达式 检查赋予它的所有类型是否都是唯一的。我尝试过这样的事情: template<class... T> inline static constexpr bool is_unique = (... && (!is_one_of<T, ...>)); 其中 is_one_of 是一个可以正确工作的类似布尔值。 但是无论我在 is_one_of 中放入什么内容,这一行都不会编译。这甚至可以使用折叠表达式来完成,还是我需要使用常规结构来实现此目的? 您的方法实际上不起作用,因为 is_one_of 需要使用类型 T 和所有其余类型 调用,不包括 T。无法通过单个参数包使用“折叠表达式”来表达这一点。我建议改用专业化: template <typename...> inline constexpr auto is_unique = std::true_type{}; template <typename T, typename... Rest> inline constexpr auto is_unique<T, Rest...> = std::bool_constant< (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...> >{}; 用途: static_assert(is_unique<>); static_assert(is_unique<int>); static_assert(is_unique<int, float, double>); static_assert(!is_unique<int, float, double, int>); wandbox.org 上的实时示例 (感谢Barry使用折叠表达式进行简化。) --编辑-- 谷歌搜索我发现了一个有趣的解决方案,它给了我灵感来避免递归并避免很多警告 因此您可以定义类型的包装器 template <typename> struct wrapT { }; 以及从类型包装器继承的类型和整数包装器 template <typename T, std::size_t> struct wrapTI : public wrapT<T> { }; 接下来,您可以定义一个 foo 类,该类 递归 继承自 wrapTI template <typename T, typename = std::make_index_sequence<std::tuple_size<T>::value>> struct foo; template <typename ... Ts, std::size_t ... Is> struct foo<std::tuple<Ts...>, std::index_sequence<Is...>> : public wrapTI<Ts, Is>... { }; 现在is_unique可以是这样的 template <typename ... Ts> static constexpr bool isUnique = ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value ); 重点是,只有当foo<Ts...>从wrapT<T>继承一次(且仅一次)时,foo<Ts...>才能转换为wrapT<T>,也就是说,如果T出现一次(且仅出现一次)在Ts...。 以下是完整的编译示例 #include <tuple> #include <type_traits> template <typename> struct wrapT { }; template <typename T, std::size_t> struct wrapTI : public wrapT<T> { }; template <typename T, typename = std::make_index_sequence<std::tuple_size<T>::value>> struct foo; template <typename ... Ts, std::size_t ... Is> struct foo<std::tuple<Ts...>, std::index_sequence<Is...>> : public wrapTI<Ts, Is>... { }; template <typename ... Ts> static constexpr bool isUnique = ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value ); int main () { static_assert( true == isUnique<int, long, long long> ); static_assert( false == isUnique<int, long, long long, int> ); }

回答 2 投票 0

c++20 具有概念和可变参数模板参数的部分类专业化

想要了解为什么下面的代码会导致: 类模板部分特化并不比主模板更特化 模板 结构...

回答 1 投票 0

可变模板包扩展

Andrei 在 GoingNative 2012 的演讲中谈到了可变参数模板,并一度通过下面的示例解释了参数包扩展的工作原理。对此还很陌生

回答 2 投票 0

如何使用包扩展循环遍历参数包?

我正在尝试学习可变参数模板和函数。我不明白为什么这段代码不能编译: 模板 静态无效栏(T t){} 模板 静态...

回答 6 投票 0

以下哪些模仿 C++17 之前的折叠表达式的技术被认为是惯用的?

C++11 和 C++14 中的折叠式表达式:惯用方法? Q&A Variadic 模板包扩展的公认答案使用了常见的 pre-C++17(折叠表达式之前)appro...

回答 1 投票 0

如何循环遍历可变参数列表[重复]

当我尝试通过以下函数迭代可变参数时 我不明白 '{(Print(Param),0)... } ' 其中使用 0 #包括 使用命名空间 std; 模板 当我尝试通过以下函数迭代可变参数时 我不明白 '{(Print(Param),0)... } ' 其中使用了 0 #include<iostream> using namespace std; template<typename T> void Print(T& arg) { cout << arg << endl; } template<typename ...ParamTypes> void Func(ParamTypes &...Param) { int arr[] = { (Print(Param),0)... }; } int main() { int num = 10; Func(num,num,num); return 0; } 当我不添加 0 时,它会给我一个错误 这是 C++17 折叠表达式的 C++14 解决方法,您可以在其中编写: template<typename ...ParamTypes> void Func(ParamTypes &...Param) { (Print(Param),... ); } Print(Param),0 调用 Print,丢弃结果(如果有)并计算为 0。 int arr[] = { (Print(Param),0)... }; 创建一堆零的数组,但对于 C++14,这是可以扩展可变参数包的少数地方之一。 就像 Print 一样,如果(模板)函数返回 void,则需要一些技巧来在表达式中操作它。这里: int arr[] = { (Print(Param),0)... }; 逗号运算符 (,) 用于确保 Print 的副作用显现出来,但会返回一些内容:零 int。事实上,你无法构造一个 void 数组。 提醒一下,逗号运算符计算其左侧操作数,丢弃其结果,最后返回其右侧操作数。 以我的拙见,这是一个糟糕的黑客行为。可以构建更清晰/明确的: struct side_effect_t { side_effect_t(...) {} }; template<typename T> side_effect_t Print(T& arg) { std::cout << arg << '\n'; return {}; } template<typename ...ParamTypes> void Func(ParamTypes &...Param) { side_effect_t{ Print(Param)... }; } godbold 演示

回答 2 投票 0

如何验证两个嵌套变体共享相同类型

代码使用嵌套的 std::variants 来建模消息: A 类{}; B 类{}; C 类{}; D 类{}; 使用 CMD1 = std::variant; 使用 CMD2 = std::variant; 使用 CMD = std::vari...

回答 1 投票 0

带约束的可变参数模板的“requires”表达式的语法是什么?

如果我有一个可变参数模板; 模板 概念 Fooable = require (T t) { t.bar() -> bool; }; 结构体 Foo { int big_foo; 模板 如果我有一个可变参数模板; template<typename T> concept Fooable = requires (T t) { t.bar() -> bool; }; struct Foo { int big_foo; template<std::Integral T, Fooable ... U> explicit Foo(T&& i, U&& ... f) noexcept : big_foo {std::forward<T>(i)} { Something::something(std::forward<U>(f)...); ... } }; 然后模板的定义及其约束将按预期工作。 但是如果我“要求”对 Foo 有更多约束,因此使用“要求”表达式格式,例如; template<typename T, typename ... U> requires std::Integral<T> && Fooable<U> && BillyBobable<U> // WHAT GOES HERE? ELLIPSIS... BUT WHERE? explicit Foo(T&& i, U&& ... f) noexcept : big_foo {std::forward<T>(i)} { SOMETHING::something(std::forward<U>(f)...); ... } 然后:我应该使用什么作为变量 U 的语法来在表达式中扩展它? 您可以在此处使用常用的 C++17 折叠表达式语法: template<typename T, typename ... U> requires std::Integral<T> && ((Fooable_concept<U> && BillyBobable_concept<U>) && ...) explicit Foo(T&& i, U&& ... f) noexcept 或者,您可以通过引入合并两者的新概念来回到之前的语法: template <typename T> concept FooAndBillyBob = Fooable_concept<T> && BillyBobable_concept<T>; template <std::Integral T, FooAndBillyBob ... U> explicit Foo(T&& i, U&& ... f) noexcept 注意:请不要说出你的概念*_concept

回答 1 投票 0

具有可变数量模板参数的 CTAD

对于单元测试,我编写了一个 ScopeSet 类,它更改当前作用域中的变量值,并在作用域结束时恢复原始值。 使用示例: 整数 i = 1; 双...

回答 1 投票 0

从不同的数据类型(字符串文字、整数变量、布尔值等)创建单个字符串。通过使用 cpp 中可用的可变模板变量

#define DLT_LOG(...)prepare_String(__VA_ARGS__) 模板 std::stringprepareMsg(Msg... 消息) { std::stringstream 流消息; (流消息<< ... << message) <&l...

回答 1 投票 0

仅包含可转换为 T 的类型的参数包

考虑以下简单的向量类: #包括 #包括 模板 类向量 { 民众: 向量()=默认值; 矢量...

回答 1 投票 0

有没有办法存储特定类型C++的可变参数模板

假设我有以下场景,我正在打印 std::size_t 类型的模板。 模板 void print_sizes(){std::cout< 假设我有以下场景,其中我正在打印 std::size_t 类型的模板。 template<std::size_t st> void print_sizes(){std::cout<<st<<std::endl;} template<std::size_t st, std::size_t M, std::size_t... Rest> void print_sizes(){ std::cout<<st<<std::endl; } int main(){ print_sizes<10, 12, 3>(); return 0; } 以上内容完全有效。但是,我想知道是否有一种方法可以存储 10,12,3 可变参数模板,如下所示: template<std::size_t st> void print_sizes(){std::cout<<st<<std::endl;} template<std::size_t st, std::size_t M, std::size_t... Rest> void print_sizes(){ std::cout<<st<<std::endl; print_sizes<M, Rest...>(); } using example = 10,12,3; int main(){ print_sizes<example>(); return 0; } 显然,这不起作用并会引发错误。有没有办法做这样的事情? 你不能轻易存储10, 12, 3参数包,但你可以存储实例化的模板: #include <iostream> template<std::size_t st> void print_sizes(){std::cout<<st<<std::endl;} template<std::size_t st, std::size_t M, std::size_t... Rest> void print_sizes(){ std::cout<<st<<std::endl; print_sizes<M, Rest...>(); } int main(){ auto f = print_sizes<10, 12, 3>; // save instantiated template f(); // invoke it. return 0; }

回答 1 投票 0

可变参数模板推演失败

我正在尝试使操作管道类型安全。下面的代码已大大简化,但我相信它具有必要的部分。 我已经尝试了可变参数的大多数组合和顺序...

回答 1 投票 0

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