可变参数模板类

Variadic Templated class

提问人:Vicror 提问时间:8/4/2023 最后编辑:JeJoVicror 更新时间:8/5/2023 访问量:74

问:

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;
}
C++ 元组 variadic-templates 类模板

评论

3赞 Yksisarvinen 8/4/2023
是的,它被称为 std::tuple。您似乎正在尝试重新实现它。

答:

4赞 Jan Schultke 8/4/2023 #1

是的,您的问题的解决方案已经以 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::tuplestd::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;
}
2赞 JeJo 8/4/2023 #2

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 中的现场演示