如何获取参数包的前n个元素?或者最后 n 个元素,或者 [n, n+1, ..., m) 中的一片元素?例如:
head<3>(1, 2.0f, "three", '4') => make_tuple(1, 2.0f, "three")
tail<2>(1, 2.0f, "three", '4') => make_tuple("three", '4')
slice<1,3>(1, 2.0f, "three", '4') => make_tuple(2.0, "three")
Run Code Online (Sandbox Code Playgroud)
这可以通过 std::tuple、std::integer_sequence 和 std::get 的组合来实现,但我想知道是否有更简单的方法。
我有一个例子来说明我的问题:
#include <utility>
class Foo {
public:
Foo(int i) {}
};
template<typename T, typename ...Args>
class Bar {
public:
T t;
Bar(Args &&... args) : t(std::forward<Args>(args)...) {}
};
Run Code Online (Sandbox Code Playgroud)
如果我想实例化这个模板:
Bar<Foo> foo(1);
Run Code Online (Sandbox Code Playgroud)
编译器抛出一个错误:
no matching function for call to ‘Bar<Foo>::Bar(int)’
Run Code Online (Sandbox Code Playgroud)
所以我必须写信给这个:
Bar<Foo, int> foo(1);
Run Code Online (Sandbox Code Playgroud)
这很烦人,尤其是当我得到一些包含一长串参数的类时。
那么有什么方法可以摆脱在参数包中显式显示类型
我对...使用模板参数包时应该放置的位置感到困惑。
例如,在模板参数列表中,我们应该使用typename ...Ts,而在参数列表中,它变成Ts...ts。
当实例化一个模板时,它变得tuple<Ts...>最让我困惑的是std::forward<Args>(args)...,...在括号之外。在那之前,我强迫自己只记住这个,直到今天我看到这个:sizeof...(Params),我想我必须了解常规模式以避免进一步混淆。
那么有人可以帮助如何对待它...以完全了解放置它的位置吗?
我有一个带参数包的模板函数。我想将它扩展为对第二个函数的调用,同时还提供包中项目的索引。我可能可以弄清楚如何用递归来做,但我想尝试用折叠表达式来做。
这是我希望参数包扩展到的函数
template<typename T>
void addToRecord(Record& rec, int idx, T&& val)
{
// Do some stuff.
}
Run Code Online (Sandbox Code Playgroud)
这是带参数包的函数
template<typename... ARGS>
void addRecord(ARGS&& ...values)
{
Record rec;
// addToRecord(rec, ??????) How do expand 'values' here addToRecord with index of each item?
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?我意识到这并不重要,但我也在努力使用折叠表达式变得更好。
这是我的问题,我有一个基类Base、两个派生类ClassA和仅采用两个参数的ClassB形式Base,以及两个类ClassB0并ClassB1从ClassB采用三个参数派生而来。我想根据传递给函数的类型创建类实例create,如果类型派生自ClassB,则第一个参数将填充为 10。编译器总是警告没有匹配的构造函数。
#include <iostream>
#include <type_traits>
class Base {};
class ClassA : public Base {
public:
ClassA(int a, int b) : Base() {
std::cout << "ClassA: " << a << " " << b << "\n\n";
}
};
class ClassB : public Base {
public:
ClassB(int a, int b, int c) : Base() {
std::cout << "ClassB: " << a << " …Run Code Online (Sandbox Code Playgroud) 所以我有一个对的列表,其中第一个成员是一个常量整数,第二个是一个类型,无论如何将它解压缩到第一个成员的数组和第二个成员的元组中?
struct MA {}
struct MB {}
struct MC {}
template <int I, class T> struct MyPair{};
Run Code Online (Sandbox Code Playgroud)
如何制作模板元函数,使其具有以下两个成员:
MyStruct<1, MA, 2, MB, 3, MC> {
std::array<int, 3> arr = {1, 2, 3};
using Tuple = std::tuple<MA, MB, MC>;
};
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个类模板,该模板使用参数包并为参数包中包含的每种类型实现一个成员函数。
这是我到目前为止:
template <typename...T>
class Myclass {
public:
void doSomething((Some_Operator_to_divorce?) T) {
/*
* Do Something
*/
std::cout << "I did something" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
我的目标是拥有一个可以按以下方式使用的类模板:
Myclass<std::string, int, double> M;
M.doSomething("I am a String");
M.doSomething(1234);
M.doSomething(0.1234);
Run Code Online (Sandbox Code Playgroud)
凡类模板机制将创建一个实现doSomething(std::string x),一个doSomething(int x)和doSomething(double x)成员函数而不是一个doSomething(std::string x, int i, double f)成员函数。
我在网上找到了很多关于参数包可用性的例子,但我不知道它是否可以用于我的目的,或者我是否完全误解了参数包的用途。
我以为我需要解包参数包,但在阅读了很多关于解包参数包的示例后,我认为这不是正确的选择,它具有完全不同的含义。
因此,因此,我正在寻找一种“离婚”参数包的操作。
我一直在尝试捕获 std 函数 lambda 中的一些参数包参数,以便将函数保存在内存中以供将来使用。
然而,在某些情况下,如果这些捕获的参数中的任何值在捕获后被修改,则这些参数的未来使用不会达到预期的效果。
我想在我的 std 函数中存储参数包的不可变副本。
该代码将作为库实现,因此用户可以使用它来保存一些文本以供将来打印。这样我们就无法管理参数包中收到的参数。此示例必须对字符串、const char *、int、float 有效...
这是示例代码:代码链接
template <typename... Args>
void doPrint(std::ostream& out, const Args &... args)
{
using expander = int[];
(void)expander{0, (void(out << args), 0)...};
}
template<typename... Args>
void printArgs(const Args & ... args)
{
doPrint(std::cout, args...);
}
class PrintTest
{
private:
std::vector<std::function<void()>> myFunctions;
public:
template<typename... Args>
void saveText(const char * text, const Args & ... args)
{
std::function<void()> f = [this, text, args...]()
{
std::cout << text;
printArgs(args ...); …Run Code Online (Sandbox Code Playgroud) 我对模板很陌生,特别是参数包,我想知道是否可以从包中获取第一个值。
例如下面的代码:
template <typename T, typename... Args>
bool register(Args... args) {
if (!Foo<T>(args..) {
assert(std::is_same_v<std::string, args...[0]>);
std::cerr << "Failed call Foo with " + args...[0] + "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
我如何真正获得第一个值args...?
值得注意的是args..。可以包含不同的类型(字符串、布尔值等)
我有一个简单的界面设置器:
template<typename Interface>
struct FrontEnd
{
virtual void inject(Interface*& ptr, Client* client) = 0;
}
Run Code Online (Sandbox Code Playgroud)
我想通过这样的参数包来实现这些接口:
template<typename ... Is>
struct BackEnd : public FrontEnd<Is>...
{
void inject(Is*& ptr, Client* client) override
{
ptr = someStuff<Is>.get(client);
}
};
Run Code Online (Sandbox Code Playgroud)
然而,这失败了parameter pack not expanded with '...'。我在cppref中找不到类似的东西。我不知道扩展基因座应该去哪里(假设这甚至是合法的,我倾向于不合法)。知道如何为参数包中的每种类型提供覆盖吗?
c++ ×10
parameter-pack ×10
templates ×6
c++17 ×3
variadic ×2
c++11 ×1
class ×1
lambda ×1
std-function ×1