variadic-templates 相关问题

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

如何从可变参数模板类创建元组并在 C++ 中调用每个元素作为参数的成员函数?

我有一个带有可变参数模板参数的类,我正在尝试编写一个成员函数来创建一个包含可变参数的容器。我的方法是从

回答 1 投票 0

std::pair 构造函数重载采用元组如何判断元组内容是否是 r-val 引用?

对于措辞尴尬的问题表示歉意。我的不确定性基于可以大致简化为以下场景的情况。 我有一个 Foo 类,我想要一个 std::pair

回答 1 投票 0

寻找一种根据条件使用不同可变参数函子的方法

我有一个运行时布尔详细信息,如果为 false,则会排除一些打印到标准输出的信息。 要确定想法,请考虑有很多部分,例如: void add(const int a, const int b, const bool verbose) { //......

回答 1 投票 0

如何从 std::array 为可变参数构造函数生成初始值设定项列表

作为简化,假设我们有两种不同类型的引脚和一个容纳其中一种的板 // 板引脚 结构 BoardPin { }; // 另一种引脚 结构特殊引脚 { }; // 一块板...

回答 1 投票 0

通用成员函数指针作为模板参数

考虑以下代码: #包括 使用命名空间 std; 班级你好{ 民众: 无效 f(){ 计算<<"f"< 考虑这段代码: #include <iostream> using namespace std; class hello{ public: void f(){ cout<<"f"<<endl; } virtual void ff(){ cout<<"ff"<<endl; } }; #define call_mem_fn(object, ptr) ((object).*(ptr)) template<R (C::*ptr_to_mem)(Args...)> void proxycall(C& obj){ cout<<"hello"<<endl; call_mem_fn(obj, ptr_to_mem)(); } int main(){ hello obj; proxycall<&hello::f>(obj); } 当然,这不会在第 16 行编译,因为编译器不知道 R、C 和 Args 是什么。但还有另一个问题:如果试图在 ptr_to_mem 之前定义这些模板参数,他会遇到这种糟糕的情况: template<typename R, typename C, typename... Args, R (C::*ptr_to_mem)(Args...)> // ^variadic template, but not as last parameter! void proxycall(C& obj){ cout<<"hello"<<endl; call_mem_fn(obj, ptr_to_mem)(); } int main(){ hello obj; proxycall<void, hello, &hello::f>(obj); } 令人惊讶的是,g++ 并没有抱怨 Args 不是模板列表中的最后一个参数,但无论如何它无法将 proxycall 绑定到正确的模板函数,只是指出它是一个可能的候选者。 有什么解决办法吗?我的最后一招是将成员函数指针作为参数传递,但如果我可以将它作为模板参数传递,它将更适合我的代码的其余部分。 编辑: 正如一些人指出的那样,这个例子似乎毫无意义,因为 proxycall 不会传递任何参数。在我正在处理的实际代码中,情况并非如此:参数是通过一些模板技巧从 Lua 堆栈中获取的。但这部分代码与问题无关,而且相当冗长,所以我不会将其粘贴到这里。 你可以尝试这样的事情: template <typename T, typename R, typename ...Args> R proxycall(T & obj, R (T::*mf)(Args...), Args &&... args) { return (obj.*mf)(std::forward<Args>(args)...); } 用途:proxycall(obj, &hello::f); 或者,要将 PTMF 变成模板参数,请尝试专业化: template <typename T, T> struct proxy; template <typename T, typename R, typename ...Args, R (T::*mf)(Args...)> struct proxy<R (T::*)(Args...), mf> { static R call(T & obj, Args &&... args) { return (obj.*mf)(std::forward<Args>(args)...); } }; 用途: hello obj; proxy<void(hello::*)(), &hello::f>::call(obj); // or typedef proxy<void(hello::*)(), &hello::f> hello_proxy; hello_proxy::call(obj); 在现代 C++ 中,可以使用 template<auto> 和通用 lambda 包装器: #include <utility> #include <functional> template<auto mf, typename T> auto make_proxy(T && obj) { return [&obj] (auto &&... args) { return (std::forward<T>(obj).*mf)(std::forward<decltype(args)>(args)...); }; } struct R {}; struct A {}; struct B {}; struct Foo { R f(A &&, const B &) { return {}; } //R f(A &&, const B &) const { return {}; } }; int main() { Foo foo; make_proxy<&Foo::f>(foo)(A{}, B{}); //make_proxy<static_cast<R (Foo::*)(A &&, const B &) const>(&Foo::f)>(std::as_const(foo))(A{}, B{}); //make_proxy<static_cast<R (Foo::*)(A &&, const B &)>(&Foo::f)>(foo)(A{}, B{}); } 如果存在重载,应该像注释代码中那样显式指定成员函数类型。

回答 2 投票 0

如何在 C++20 中定义一个概念来检查类型是否与类型列表中的任何类型匹配

我想用C++定义一个概念(<= C++20) to check if a type matches any of the types define in a type-list struct. The following is my attempt so far: template 结构

回答 1 投票 0

在发送到 std::vformat 之前如何转换可变参数的类型

我想在将来自可变参数的特定类型的值发送到 std::vformat() 之前对其进行转换,但我似乎找不到一种方法来实现它。 我尝试获取格式参数...

回答 1 投票 0

在C++中,如何使用模板接受任意格式的聚合初始化列表?

例如,考虑函数 foo,可以按如下方式调用它: 富( {{1.0f}, 123}, {'C', {}} ); 函数中的每个参数位置都可以采用聚合初始化 l...

回答 1 投票 0

如何使用折叠表达式实现“多米诺骨牌”或“级联”更新功能?

我正在编写一个可变参数模板函数,它应该实现“多米诺骨牌”更新。也就是说:给定一个谓词 p,它应该迭代多个 lval(通过引用传递)和 ass...

回答 2 投票 0

如何在 C++ 中创建不同类型的多个向量的组合,而无需硬编码循环

以下问题询问如何查找相同类型的 n 个向量的“所有组合”,例如std::string:如何在 C++ 中创建多个向量的组合而无需硬编码循环?...

回答 1 投票 0

为什么被认为是编译时的文字不知道?

您好,我有一个非常具体的问题,我已经尝试解决这个问题几个小时了。 我有一个能够将字符串存储为模板参数的关键类。我想用它来实现...

回答 1 投票 0

std::print() 和模板参数包

可以使用 std::print 打印模板参数包吗? 就像是: 无效函数(自动...参数){ std::print("???", args...); }

回答 1 投票 0

C++:使用折叠表达式实现“多米诺骨牌更新”

考虑以下代码: #包括 #包括 模板 无效 dominoe_update(P, Val&) {} 模板 考虑以下代码: #include <iostream> #include <functional> template<class Val, class P> void dominoe_update(P, Val&) {} template<class Val, class Lval, class... More, class P> void dominoe_update(P p, Val&& val, Lval& lval, More&... more) { if (p(val, lval)) { lval = val; // No need to forward since it'd potentialy chain more copies anyway dominoe_update(p, val, more...); } } int main(int, char**) { int i = 8, j = 9, k = 1; dominoe_update(std::less{}, 2, i, j, k); std::cout << i << ' ' << j << ' ' << k << '\n'; // Prints 2 2 1 return 0; } dominoe_update 使用 val 更新所有参数,直到 p 返回 false。 是否可以使用折叠表达式来实现上述函数以删除递归并删除基本情况函数?我认为这是不可能的,因为短路逻辑。 这是一种方法: template <class P, class Val, class... Lvals> void dominoe_update(P p, Val&& val, Lvals&&... lval) { ((/*if*/ p(val, lval) /*then*/ && (lval = val, true)) /*and next*/ && ...); } 演示 接受挑战。 template<typename P, typename Val, typename... Lval> void dominoe_update(P p, Val&& val, Lval&... lval) { bool go = true; ( (go && (go = p(val, lval)) ? (void(lval = val), 0) : 0), ...); } 演示

回答 2 投票 0

C++:使用折叠表达式进行编译时“多米诺骨牌更新”

考虑以下代码: #包括 #包括 模板 无效 dominoe_update(P, Val&) {} 模板 考虑以下代码: #include <iostream> #include <functional> template<class Val, class P> void dominoe_update(P, Val&) {} template<class Val, class Lval, class... More, class P> void dominoe_update(P p, Val&& val, Lval& lval, More&... more) { if (p(val, lval)) { lval = val; // No need to forward since it'd potentialy chain more copies anyway dominoe_update(p, val, more...); } } int main(int, char**) { int i = 8, j = 9, k = 1; dominoe_update(std::less{}, 2, i, j, k); std::cout << i << ' ' << j << ' ' << k << '\n'; // Prints 2 2 1 return 0; } dominoe_update 使用 val 更新所有参数,直到 p 返回 false。 主要问题:是否可以使用折叠表达式来实现上述函数以删除递归并删除基本情况函数?我认为这是不可能的,因为短路逻辑。 第二个问题:是否可以将谓词写为最后一个参数,而不是第一个?我知道在可变参数之后写参数是“复杂的”,但我认为在某些情况下推导规则允许这样做。 第三个问题:你认为这个函数有更好的名字吗?我正在考虑为常见情况提供一些实用函数,例如最小化和最大化,但是 dominoe_minimize 和 dominoe_maximize 作为通用名称对我来说听起来不太好。 接受挑战。 template<typename P, typename Val, typename... Lval> void dominoe_update(P p, Val&& val, Lval&... lval) { bool go = true; ( (go && (go = p(val, lval)) ? (void(lval = val), 0) : 0), ...); } 演示

回答 1 投票 0

在 C++ 模块中将可变数量的参数转发到 SpdLog

我是一名专业的 C# 开发人员,正在启动一个 C++ 副项目。我的第一步是使用 spdlog 进行记录和运行。由于这是一个新的现代项目,我正在使用模块。 ...

回答 1 投票 0

可变参数类的多重继承

我可以执行以下操作吗? 模板 A类{}; 模板 B 类:公共 A... {}; 我期待这种行为: 模板 B 类:...

回答 1 投票 0

带有可变参数模板的 C++ 概念

多年后我又回到了 C++,并试图掌握其中的概念。我编写了一个简单的测试代码,但出现了一个错误,我不太明白为什么会出现在这里。 模板 多年后我又回到了 C++,并试图掌握其中的概念。我编写了一个简单的测试代码,但出现了一个错误,我不太明白为什么会出现在这里。 template <typename T, typename U> concept addable = requires (T a, U b) { a + b; }; template <typename T> T test_add(T&& value) { return value; } template <typename T, typename... Args> auto test_add(T&& value, Args&&... rest) requires addable<T, decltype(test_add(forward<Args>(rest)...))> { return value + test_add(forward<Args>(rest)...); } 目标是检查返回表达式上是否有有效的+操作,但是当我像这样调用函数时: auto result = test_add(1, 3, 5); 我收到以下错误:“没有重载函数“test_add”的实例与参数列表匹配”。 这里出了什么问题? 看起来您希望 concept 是可变参数,因此您需要一个参数包,然后进行包扩展: template <class... Ts> concept addable = requires(Ts&&... ts) { (... + ts); }; 您的 test_add 函数模板可以替换为 one,它使用 concept 并在 + 运算符上使用折叠表达式: auto test_add(addable auto&&... values) { return (... + std::forward<decltype(values)>(values)); }

回答 1 投票 0

选择可变参数模板最后一个参数的有效方法

我知道如何选择可变参数模板的第一个参数: template< class...Args> struct select_first; template< class A, class ...Args> struct select_first{ 使用 t...

回答 8 投票 0

如果在可变参数模板类的成员函数声明中我将类类型指定为默认模板模板参数,它是有效的 C++ 吗? [重复]

简而言之:此代码可以在 clang++ (10.0) 中编译,但不能在 g++ (12.2) 中编译。哪一个是正确的? 模板 结构体V{ 模板 类 U=V,输入 n...

回答 1 投票 0

ranges::view 管道运算符 - 通过将 std::variant 参数隐藏到变量->选项模式来实现 std::visit 的单子链?

我的灵感来自 std::ranges 和 std::view 及其 |有助于链接不同算法的运算符,所以我希望将 std::get_if 和 std::visit 模式打包在引擎盖下以执行 inpl...

回答 1 投票 0

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