可变参数模板是采用可变数量参数的模板。
我试图从 CRTP 基类中推断函数的返回类型和参数,以便“包装”函子。 从基本的 CRTP 模式开始: 模板
模板 无效 foo(T , Ts ... ) { } 模板 空条(T , Ts ... ) { } int main() { foo(1, 'c'); // 好吧...
从可变参数模板生成 std::function 的 std::tuple
假设有一个像这样的函数 模板 void f(std::tuple & 数据); 我想生成一个 std::function 的 std::tuple,每个都有这个签名:std::function<
有没有办法使用 C++ 中的可变参数模板检索类型的内部类型?
假设我有一个使用可变参数模板的类型: 模板 结构体外部 { // 使用 Inner = 捕获 ...Args ???; } 我如何定义“内在”以便我可以...
我正在尝试为基于类型的函数创建一个专门化的模板 例如,对于我所拥有的类型号 模板 我正在尝试为基于类型的函数创建一个专业化模板 例如对于我拥有的型号 template <class ElementType, typename = typename TEnableIf<TNot<TIsSame<ElementType, double>>::Value>::Type> void WriteExtras(IGLTFJsonWriter& Writer, const FString& Key, const TSharedPtr<FJsonValue>& Value) const { Writer.Write(Key, float(Value->AsNumber())); // Perform further processing or write logic for double } 现在我想要多一个定义,但对于 bool ......但如果我尝试这样做 template <class ElementType, typename = typename TEnableIf<TNot<TIsSame<ElementType, bool>>::Value>::Type> void WriteExtras(IGLTFJsonWriter& Writer, const FString& Key, const TSharedPtr<FJsonValue>& Value) const { Writer.Write(Key, Value->AsBool()); // Perform further processing or write logic for double } 我收到错误“函数已定义” 我将函数模板称为 WriteExtras< EJson>(Writer,Key,Pair.Value); EJson 是一个枚举 enum class EJson { None, Null, String, Number, Boolean, Array, Object }; 这两个函数实际上声明了同一个函数: template <class ElementType, typename = typename TEnableIf<TNot<TIsSame<ElementType, double>>::Value>::Type> void WriteExtras(IGLTFJsonWriter& Writer, const FString& Key, const TSharedPtr<FJsonValue>& Value) const; template <class ElementType, typename = typename TEnableIf<TNot<TIsSame<ElementType, bool>>::Value>::Type> void WriteExtras(IGLTFJsonWriter& Writer, const FString& Key, const TSharedPtr<FJsonValue>& Value) const; 它们之间的唯一区别是模板参数的默认参数,但这并没有使其中之一成为单独的实体。就像写作一样: int foo(int x = 0); int foo(int x = 1); 您需要在函数签名中的其他地方使用 std::enable_if (或您的自定义模仿)进行 SFINAE,例如参数、noexcept 规范、返回类型等。对于函数,最好的方法之一是使用返回类型,因为它不会改变模板参数列表: // convenience alias (since C++14) template <bool Condition, typename T = void> using EnableIf_t = typename EnableIf<Condition, T>::type; template <class ElementType> auto WriteExtras(IGLTFJsonWriter& Writer, const FString& Key, const TSharedPtr<FJsonValue>& Value) const -> TEnableIf_t<not TIsSame<ElementType, double>::Value>; template <class ElementType> auto WriteExtras(IGLTFJsonWriter& Writer, const FString& Key, const TSharedPtr<FJsonValue>& Value) const -> TEnableIf_t<not TIsSame<ElementType, bool>::Value>;
我有一个可变参数模板函数,它将文件名、分隔符和非指定数量的容器作为参数作为列。然后,该函数解析并归档容器中的所有值
Typescript - 如何从动态创建的对象推断正确的子类类型
这是这个问题的后续。 我想要达到的目标是: 将多个子类传递给函数是否有一种方法可以返回一个对象,该对象作为具有 sub-
尽管事实上,我们有 std::max,但我想尝试是否可以制作一个接受可变参数并递归调用 Max 来查找最大元素的 Max 版本。 我看到类似的...
C++ 中有没有一种方法可以创建一个模板类,该类在构造函数中接受任意数量的参数,并且可以在需要时获取这些参数? 例子: #包括 模板 C++ 中有没有一种方法可以创建一个模板类,该类在构造函数中接受任意数量的参数,并且可以在需要时获取这些参数? 示例: #include <string> template<size_t Size, typename... Types> class Container { public: Container(Types... args) { // add checks to see if Size = no args } void get(Types&... args) { // getter method } }; int main() { Container<3, int, double, std::string> container(10, 2.5, "smth"); int a{}; double b{}; std::string c {}; container.get(a, b, c); // expect a = 10, b = 2.5, c = "smth" return 0; } 是的,您的问题的解决方案已经以std::tuple的形式存在: // note: size_t parameter isn't needed, we can simply get the size using // sizeof...(Types) template<typename... Types> class Container { public: std::tuple<Types...> stuff; // note: in practice, this should use forwarding references and // std::forward instead of taking everything by value Container(Types... args) : stuff(args...) {} void get(Types&... args) { // std::tie creates a tuple of references, letting us // assign all members at once std::tie(args...) = stuff; } }; 你可以实现一个包装std::tuple的容器,但它并没有真正提供std::tuple还没有的任何实用工具,所以我们可以直接使用它: int main() { std::tuple<int, double, std::string> container(10, 2.5, "smth"); // not so good: decompose using three variables and std::tie int a {}; double b {}; std::string c {}; std::tie(a, b, c) = container; // better: use structured bindings (C++17) auto [aa, bb, cc] = container; } 请记住,在泛型编程之外,您最好创建自己的 struct,并为类型和成员提供有意义的名称。 // aggregate type struct Container { int a; double b; std::string c; }; int main() { Container container{10, 2.5, "smth"}; // structured bindings also work for aggregate types (C++17) auto [a, b, c] = container; } C++ 中有没有一种方法可以创建一个模板类,该类在构造函数中接受任意数量的参数,并且可以在需要时获取这些参数? 是的,只需在这里使用std::tuple即可。是否应该将其包装到类模板中,取决于进一步的要求。 #include <tuple> // std::tuple auto container{ std::make_tuple(10, 2.5, "smth"s) }; // Structured bindings since C++17 auto [a, b, c] = std::tuple<int, double, std::string>(container); 在 godbolt.org 中观看现场演示
问题 给定任何函数(或可调用)类型 Function,如何获取其所有参数类型作为元组类型? 例如,我需要一个特征 function_traits::arguments,其中: 我...
C++20:将参数包编码和解码为由 varargs 使用的变量
经过漫长而详尽的搜索后,不确定以下内容在 C++20 中是否可能,但无论如何还是要问: 使用 C++20 代替 C 的 va_list,我可以: (1) 对传递给变量的任意参数列表进行编码...
给定以下代码: 模板 概念对=要求(P对) { 类型名 P::first_type; 类型名 P::second_type; pair.first; 对.second; { pair.first } -&g...
我有一个简单的片段,试图说明我正在尝试做什么。 我将几个类实例打包在一个元组中,并使用 std::apply 迭代它们。 我想捕捉两个值: 如果匹配...
此代码片段实现了两个类——一个接受命令名称和受支持子命令列表的命令处理程序,以及一个包含所有此类受支持“命令”的元类。 我是
我不熟悉可变参数模板和压缩参数等等。 我想在我的程序中有一个“实体组件系统”,在尝试向实体添加组件时,我开始意识到...
我用整数参数化了一个模板类 模板 类 TemplClass{}; 然后我为 std::variant 定义了一个模板别名: 模板...
两个 C++ 编译器不同意我的“count_args”函数是否是 constexpr
这是一个小函数,可以计算您传入的参数数量: #包括 constexpr static int count_args() { 返回 0; } 模板 constexpr 站...
我有简单的 3 个类,其中两个实际上是继承的: 结构A { }; 结构 B :虚拟 A { B(整数, 整数) { } }; 结构 C : 虚拟 A { C(整数) { } }; 现在我想上一堂课......
给定重载函数 f1: void f1(int); int f1(字符); 以及一个带有成员模板 f 的类模板 X: 模板 结构 X { 模板 静态无效 f(T(*p)(U...
如何使用 pybind11 为可变参数模板调用提供 Python 绑定?
我正在尝试使用 pybind11 为具有大量可变(成员)函数或构造函数的 C++17 库创建 Python 绑定。 // 可变成员函数 结构栏 { 模板 我正在尝试使用 pybind11 为具有大量可变(成员)函数或构造函数的 C++17 库创建 Python 绑定。 // variadic member function struct Bar { template <typename... Args> void baz(Args&&...){ /*...*/ } }; // variadic constructor struct Foo { template <typename... Args> Foo(Args&&...){ /*...*/ } }; // variadic free function template <typename... Args> void foobar(Args&&...){ /*...*/ } pybind11 supports positional *args arguments 使用这个功能对我来说似乎很自然。不幸的是,我一直无法弄清楚如何使用 pybind11::args 将参数转发给可变参数函数。 绑定代码是什么样的? #include <pybind11/pybind11.h> namespace py = pybind11; PYBIND11_MODULE(example, m) { py::class_<Bar>(m, "Bar") .def("baz", [](py::args){ /* how do I forward to variadic Bar::baz? */ }); py::class_<Foo>(m, "Foo") .def(py::init<py::args>()); // is this right? m.def("foobar", [](py::args){ /* how do I forward to variadic foobar? */ }); } 这里有一些限制: 对于我的用例,在所有情况下都支持某种固定类型的异构参数就足够了,例如我可以只为 Foo 公开一个接受任意数量的 Bar 实例的构造函数。 我不能——或者非常不愿意——修改现有库的API。因此,必须使用接受例如一个std::initializer_list会让我难过。也就是说,绑定代码中的一些胶水代码是可以接受的,只要它是可维护的。 虽然肯定不漂亮,但我可以接受将可变参数的数量限制为最大值,比如 20,因为模板必须在绑定代码的编译时显式实例化,例如通过 template void foobar(); template void foobar(Foo&&); // ... 如果事实证明这是必要的,那么如果 python 用户能够得到一个适当的错误消息,表明已超过最大参数数量,那就太好了。 它不一定是 pybind11,如果其他库处理得更好,我愿意使用它们。 使用 py::cast 将 py::args 对象的每个元素转换为 int 并将它们作为参数传递给适当的 C++ 函数(这还需要在编译时了解类型): Playground #include <pybind11/pybind11.h> namespace py = pybind11; struct Bar { void baz(int x, int y) { /* ... */ } }; struct Foo { Foo(int x, int y) { /* ... */ } }; void foobar(int x, int y) { /* ... */ } // Explicitly instantiate the templates for up to 2 int arguments template void Bar::baz<int, int>(int&&, int&&); template void Foo::Foo<int, int>(int&&, int&&); template void foobar<int, int>(int&&, int&&); PYBIND11_MODULE(example, m) { py::class_<Bar>(m, "Bar") .def("baz", [](Bar& self, py::args args) { if (args.size() != 2) { throw std::runtime_error("Expected 2 arguments"); } int x = py::cast<int>(args[0]); int y = py::cast<int>(args[1]); self.baz(std::move(x), std::move(y)); }); py::class_<Foo>(m, "Foo") .def(py::init<int, int>()); m.def("foobar", [](py::args args) { if (args.size() != 2) { throw std::runtime_error("Expected 2 arguments"); } int x = py::cast<int>(args[0]); int y = py::cast<int>(args[1]); foobar(std::move(x), std::move(y)); }); }