【问题标题】:Iterate through template parameter遍历模板参数
【发布时间】:2020-02-19 10:46:03
【问题描述】:

我有一个接收模板参数的函数。

template<class Container>
void function(const Container& object)
{
     //here i want to iterate through object and print them
}

int main()
{
     function(std::vector<int>{1,3,6,7});
     function(std::vector<std::vector<int>>{{1,2,3},{2,5,7}});
}

是否可以在一个函数中执行此操作?假设容器参数是整数。

【问题讨论】:

    标签: c++ templates stl generic-programming


    【解决方案1】:

    一个例子:

    template<class T>
    void print(T const& object) {
        std::cout << object;
    }
    
    template<class... Args>
    void print(std::vector<Args...> const& container) {
        for(auto const& element : container) {
            print(element);
            std::cout << ' ';
        }
        std::cout << '\n';
    }
    
    int main() {
         print(std::vector<int>{1,3,6,7});
         print(std::vector<std::vector<int>>{{1,2,3},{2,5,7}});
    }
    

    【讨论】:

    • 我将其命名为 std::ostream &amp; operator&lt;&lt;(std::ostream &amp;, std::vector&lt;Args...&gt; const&amp;) 而不是 void print(std::vector&lt;Args...&gt; const&amp;)
    • @Caleth 这可能会导致 ADL 和 ODR 出现问题,因为 operator&lt;&lt; 不能放入 std::,但它的参数来自 std::。这样operator&lt;&lt; 必须在全局命名空间中,这可能会与定义相同运算符的其他智能用户发生冲突。
    • “在一个功能中”。挑剔;-)
    【解决方案2】:

    这应该适用于您的情况。请注意,我正在使用@Jarod42 https://stackoverflow.com/a/29634934/8192043 在这个惊人的解决方案中实现的特征。

    template<template<typename ...> typename C, typename D, typename ... Others>
    void function(const C<D, Others...> &object)
    {
        if constexpr(is_iterable<D>::value)
        {
           for(const auto& v : object)
           {
               for (const auto& w : v)
               {...}
           }
        }
        else
        {
           for (const auto& w : object)
           {...}
        }
    }
    

    【讨论】:

    • std::vector 有 3 个模板参数,其他容器或多或少有。只有当容器模板参数的其余部分是默认值时,您的代码才能工作。
    • 我们可以通过用这个template&lt;template&lt;typename...&gt; typename C, typename D, typename... Others&gt; void function(const C&lt;D, Others...&gt; &amp;object)替换声明来克服
    • @arnes 应该只是template&lt;class T&gt; void function(T const&amp; object)
    • @MaximEgorushkin 我认为这不是约束或限制,只是他尝试打印。
    • @MaximEgorushkin 想了很多,是的,我和你的解决方案一样。谢谢,你有我的 +1。
    【解决方案3】:

    使用is_iterable traits,您可以这样做:

    template<typename Container>
    void function(const Container& object)
    {
        if constexpr(is_iterable<std::decay_t<*object.begin()>>::value)
        {
           for(const auto& v : object)
           {
               function(v); // recursive call
           }
        }
        else
        {
            for (const auto& w : object)
            {
                // ...
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-16
      • 2022-12-11
      • 2011-11-06
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 1970-01-01
      相关资源
      最近更新 更多