标签: parameter-pack

C++:获取参数包的头和尾

如何获取参数包的前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 的组合来实现,但我想知道是否有更简单的方法。

c++ templates variadic parameter-pack

5
推荐指数
1
解决办法
901
查看次数

实例化模板时是否必须显式显示参数包中的类型?

我有一个例子来说明我的问题:

#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)

这很烦人,尤其是当我得到一些包含一长串参数的类时。

那么有什么方法可以摆脱在参数包中显式显示类型

c++ parameter-pack

4
推荐指数
1
解决办法
70
查看次数

是否有任何常规模式可以确定将...放在模板中的位置?

我对...使用模板参数包时应该放置的位置感到困惑。

例如,在模板参数列表中,我们应该使用typename ...Ts,而在参数列表中,它变成Ts...ts

当实例化一个模板时,它变得tuple<Ts...>最让我困惑的是std::forward<Args>(args)......在括号之外。在那之前,我强迫自己只记住这个,直到今天我看到这个:sizeof...(Params),我想我必须了解常规模式以避免进一步混淆。

那么有人可以帮助如何对待它...以完全了解放置它的位置吗?

c++ templates parameter-pack

4
推荐指数
1
解决办法
59
查看次数

使用折叠表达式扩展带有索引的参数包

我有一个带参数包的模板函数。我想将它扩展为对第二个函数的调用,同时还提供包中项目的索引。我可能可以弄清楚如何用递归来做,但我想尝试用折叠表达式来做。

这是我希望参数包扩展到的函数

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)

这可能吗?我意识到这并不重要,但我也在努力使用折叠表达式变得更好。

c++ fold-expression c++17 parameter-pack

4
推荐指数
2
解决办法
72
查看次数

如何根据模板函数中的类型构造不同的对象?

这是我的问题,我有一个基类Base、两个派生类ClassA和仅采用两个参数的ClassB形式Base,以及两个类ClassB0ClassB1ClassB采用三个参数派生而来。我想根据传递给函数的类型创建类实例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)

c++ templates variadic-templates parameter-pack

3
推荐指数
1
解决办法
87
查看次数

将成对的参数包解包成一个数组和一个元组

所以我有一个对的列表,其中第一个成员是一个常量整数,第二个是一个类型,无论如何将它解压缩到第一个成员的数组和第二个成员的元组中?

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)

c++ templates variadic-templates c++17 parameter-pack

3
推荐指数
1
解决办法
54
查看次数

分离类模板中的参数包

我正在尝试编写一个类模板,该模板使用参数包并为参数包中包含的每种类型实现一个成员函数。

这是我到目前为止:

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)成员函数。

我在网上找到了很多关于参数包可用性的例子,但我不知道它是否可以用于我的目的,或者我是否完全误解了参数包的用途。

我以为我需要解包参数包,但在阅读了很多关于解包参数包的示例后,我认为这不是正确的选择,它具有完全不同的含义。

因此,因此,我正在寻找一种“离婚”参数包的操作。

c++ templates class variadic parameter-pack

2
推荐指数
1
解决办法
82
查看次数

如何在 std 函数 lambda c++ 11 中正确捕获参数包

我一直在尝试捕获 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)

c++ lambda c++11 std-function parameter-pack

2
推荐指数
1
解决办法
255
查看次数

从模板参数包 C++ 中解压第一个参数

我对模板很陌生,特别是参数包,我想知道是否可以从包中获取第一个值。

例如下面的代码:

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..。可以包含不同的类型(字符串、布尔值等)

c++ templates parameter-pack

2
推荐指数
2
解决办法
2608
查看次数

覆盖参数包声明和扩展位点

我有一个简单的界面设置器:

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++ variadic-templates c++17 parameter-pack

2
推荐指数
1
解决办法
106
查看次数