当函数返回由模板类型和另一个模板类型组成的类型时,模板参数推导

时间:2017-05-27 00:26:09

标签: c++ templates metaprogramming template-meta-programming c++17

标题很难用词来表达,但这是我试图在不可编译的代码中实现的:

template<template <typename> class Container>
Container<int> foo() {
    return Container<int>{1,2,3};
}

int main() {
    auto bar = foo<std::vector>();
    return 0;
}

基本上我想要一个模板函数,它可以从传递给它的类型和先前已知的类型(在本例中为int)“组合”它的返回类型。在这种情况下,我想要一个函数,它在调用者指定的容器内返回任意数据类型。 (任意我不是指在编译时是随机的或未确定的,而是调用者没有关于数据类型的“输入”,这是在函数本身内部确定的。)

这种类型的东西甚至可以通过使用std + 1z的clang或gcc来实现吗?我错过了一些非常明显的东西吗是否有一个“1行”解决方案,涵盖了我不知道的数百个角色?

我在这里看到了类似事物的各种例子,但它们似乎都假设函数将指针或引用作为参数并填充这些容器。

2 个答案:

答案 0 :(得分:5)

这里唯一的麻烦是std::vector 一个template <typename> class。它是一个template <typename T, typename Alloc> class碰巧有第二个模板参数的默认参数。

解决此问题的一种方法是使用别名模板,该模板实际上只需要一个参数:

#include <vector>

template<template <typename> class Container>
Container<int> foo() {
    return Container<int>{1,2,3};
}

template <typename T>
using Vec = std::vector<T>;

int main() {
    auto bar = foo<Vec>();
    return 0;
}

注释中建议的另一种方法是在声明原始函数的模板时使用可变参数类型名称,该模板接受仅采用类型参数的任何类模板。然后你可以用一个参数来实例化它,因为实际的模板有第二个参数的默认值。这适用于C ++ 11及更高版本。

#include <vector>

template<template <typename...> class Container>
Container<int> foo() {
    return Container<int>{1,2,3};
}

int main() {
    auto bar = foo<std::vector>();
    return 0;
}

答案 1 :(得分:3)

带有queryparam 模板模板参数列表模板模板参数将绑定到任何模板名称,而不管实际的模板参数数。您可以使用它并推测假设模板可以使用单个参数进行实例化。

url?id=1?postId=1&postId=2

据我所知,自typename...开始就有效。

也可以使用单个参数声明模板化别名,使界面更具自我记录性

template<template <typename...> class Container>
Container<int> foo() {
    return Container<int>{1,2,3};
}

int main() {
    auto bar = foo<std::vector>();
    return 0;
}