c++ - 如何在 C++ 中使用嵌套模板?

标签 c++ templates

我是 C++ 的新手,现在正在用它上课。作为家庭作业,我们应该编写一个接受任何容器作为输入但不使用迭代器的函数。所以我们不能只传递 std::begin(container)std::end(container) 作为参数。我们必须将容器作为引用传递。我对此的看法是以下函数声明:

template <typename T, typename U, typename V, template <typename a, typename b> typename container>
void doStuff(container<T, U>& first, container<T, V>& second)
{
    // the code
}

它接受两个容器(或任何使用两个模板参数的模板类型)。 container 中的第二个模板参数不同,因为在数组中 V 可能代表数组的大小,我希望能够接受两个不同大小的数组。

示例:

std::array<bool, 4> a1 = { true, false, false, false };
std::array<bool, 1> a2 = { false };

不幸的是,这个例子不起作用。该错误表明我 doStuff 不接受这些类型的参数。这是为什么?

在我看来,在这里使用“模板化模板”很重要,因为我想确保该函数只接受包含相同类型数据的两个容器。因此传递一个 int 数组和一个 double 数组应该是行不通的。

最佳答案

如果你想支持尽可能多的容器类型,你应该使用尽可能少的限制定义:

template <typename FirstContainer, typename SecondContainer>
void doStuff(FirstContainer& first, SecondContainer& second)
{
}

这是因为容器类型有各种各样的风格,例如std::array 是一个以值类型和静态大小作为参数的模板,std::vector 是一个以值类型和分配器为参数的模板,一些自定义 StringList 可能根本不是模板。

您的实现可能对支持的容器有一些特定要求,例如它可能只适用于整数类型的容器。但通常这只是实现的隐含结果。以一个简单的函数为例,将两个容器的值相加:

template <typename FirstContainer, typename SecondContainer>
int sum(const FirstContainer& first, const SecondContainer& second)
{
    int result = 0;
    for (auto value : first)
        result += value;
    for (auto value : second)
        result += value;
    return result;
}

此函数适用于可以添加到整数的任何值类型。如果无法添加(如 std::string),最终将导致编译错误。

(请注意,可以使用自动推导的总和类型来编写更通用的函数,而不仅仅是 int)

如果这些“隐式要求”对您来说还不够,您可以使用 static_assert 添加显式检查:

template <typename FirstContainer, typename SecondContainer>
int sum(const FirstContainer& first, const SecondContainer& second)
{
    int result = 0;
    for (auto value : first)
    {
        static_assert(std::is_same_v<int, decltype(value)>, "FirstContainer does not hold integers");
        result += value;
    }
    for (auto value : second)
    {
        static_assert(std::is_same_v<int, decltype(value)>, "SecondContainer does not hold integers");
        result += value;
    }
    return result;
}

现在您的函数只接受包含普通 int 的容器,没有其他内容。

您还可以使用 std::enable_if 为不受支持的容器完全“禁用”您的功能:

template <typename FirstContainer, typename SecondContainer>
auto sum(const FirstContainer& first, const SecondContainer& second)
    -> std::enable_if_t<
        std::is_same_v<typename FirstContainer::value_type, int> &&
        std::is_same_v<typename SecondContainer::value_type, int>,
        int
    >
{
    int result = 0;
    for (auto value : first)
        result += value;
    for (auto value : second)
        result += value;
    return result;
}

现在您的函数仅限于具有嵌套 typedef value_type 以键入 int 的容器。

关于c++ - 如何在 C++ 中使用嵌套模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56915795/

相关文章:

c++ - 是否可以使用 CRTP 访问父类主体内的成员?

templates - 如何在jade模板之间传递变量

c++ - 我如何获得代码::blocks to keep the libraries configured after code::blocks restarts?

c++ - 在 C++ 中使用函数或类来完成简单任务?

c++ - 是否喜欢更长的生命周期/更大范围的局部变量?

c++ - 使用 std::array<Type, N> 的实例作为模板参数

c++ - 有没有办法强制用户显式指定模板参数类型?

c++ - COM 函数产生不会消失的线程

c++ - 我的 QuadTree 实现遇到问题

c++ - 在模板特化的情况下,是否允许编译器忽略内联?