Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
实现函数模板以填充多维对象 填充C++中的多维对象(数组、嵌套标准容器等)一直让我恼火。通常使用嵌套循环。例如,要用值v填充三维对象obj,可以编写如下代码 for (auto& x : obj) { for (auto& y : x) { for (auto& z : y) { z = v; } } } fill(obj, v);_C++_Arrays_Multidimensional Array_C++14_Template Meta Programming - Fatal编程技术网

实现函数模板以填充多维对象 填充C++中的多维对象(数组、嵌套标准容器等)一直让我恼火。通常使用嵌套循环。例如,要用值v填充三维对象obj,可以编写如下代码 for (auto& x : obj) { for (auto& y : x) { for (auto& z : y) { z = v; } } } fill(obj, v);

实现函数模板以填充多维对象 填充C++中的多维对象(数组、嵌套标准容器等)一直让我恼火。通常使用嵌套循环。例如,要用值v填充三维对象obj,可以编写如下代码 for (auto& x : obj) { for (auto& y : x) { for (auto& z : y) { z = v; } } } fill(obj, v);,c++,arrays,multidimensional-array,c++14,template-meta-programming,C++,Arrays,Multidimensional Array,C++14,Template Meta Programming,这样的循环是代码噪音,编写起来很枯燥,也会妨碍代码读取。我正在考虑编写一个函数模板来执行填充。理想情况下,有了这样一个函数模板,您应该能够编写 for (auto& x : obj) { for (auto& y : x) { for (auto& z : y) { z = v; } } } fill(obj, v); 有什么想法吗 目前,我有一个制作多维对象的函数模板。所以你可以 // assuming `obj` is a 3x

这样的循环是代码噪音,编写起来很枯燥,也会妨碍代码读取。我正在考虑编写一个函数模板来执行填充。理想情况下,有了这样一个函数模板,您应该能够编写

for (auto& x : obj) {
  for (auto& y : x) {
    for (auto& z : y) {
      z = v;
    }
  }
}
fill(obj, v);
有什么想法吗

目前,我有一个制作多维对象的函数模板。所以你可以

// assuming `obj` is a 3x3x3 nested `std::vector`
obj = make_multi<std::vector>(v, 3, 3, 3);
//假设'obj'是一个3x3x3嵌套的'std::vector`
obj=使多(v,3,3,3);

除了比理想情况更多的代码之外,这个解决方案是一个性能噩梦。最后,我必须寻找更好的方法。

您可以编写一个扁平的foreach:

namespace detail {
    template <typename Range, typename Func>
    constexpr auto flat_foreach(Range&& r, Func& f, int)
        -> decltype(void(f(std::forward<Range>(r)))) {f(std::forward<Range>(r));}

    template <typename Range, typename Func>
    constexpr void flat_foreach(Range&& r, Func& f...) {
        for (auto&& i : r)
            flat_foreach(std::forward<decltype(i)>(i), f, 0);
    }
}

template <typename Range, typename Func>
constexpr void flat_foreach(Range&& r, Func f) 
{detail::flat_foreach(std::forward<Range>(r), f, 0);}
名称空间详细信息{
模板
constexpr自动展开(范围和范围、函数和函数、整数)
->decltype(void(f(std::forward(r))){f(std::forward(r));}
模板
constexpr void flat_foreach(范围和范围、函数和函数…){
用于(自动和输入:r)
扁平前刀(标准:向前(i),f,0);
}
}
模板
constexpr void flat_foreach(范围和范围,函数f)
{detail::flat_foreach(std::forward(r),f,0);}

。这是一种非贪婪的方法,将范围传递给尽可能浅的给定函数

以下是贪婪的对应:

名称空间详细信息{
使用std::begin;
使用std::end;
模板
constexpr void flat_foreach(Elem&e、Func&f、long){
f(std::forward(e));
}
模板
constexpr自动展开(范围和范围、函数和函数、整数)
->decltype(开始(r),无效(结束(r))){
用于(自动和输入:r){
扁平前刀(标准:向前(i),f,0);
}
}
}
模板
constexpr void flat_foreach(范围和范围,函数f){
细部:扁平前端(标准:前端(r)、f、0);
}


这种方法的一般优点是,如果初始化的值从未更改,那么可以为
f

传入一个通用lambda/函子,为什么不使用构造函数呢?@NathanOliver多维对象的构造时可能不知道要使用的值。然后延迟构造,直到知道价值我不认为你会使用它,直到你知道用什么填充它。哦,我的天。。。这样一个困难的任务(至少在我看来)可以得到这样一个优雅的解决方案!你真厉害!这个东西肯定应该添加到标准库中@Columbo我很想看到对此的解释,因为我对你的解决方案印象深刻,但我真的不明白它是如何工作的。@RamboRamon如果第一个过载不匹配,则选择第二个过载。当表达式
f(std::forward(r))
有效时,第一个重载匹配,即当给定的函子适用于
r
@Columbo给定的子范围时感谢您的评论,我想我现在就明白了。真的很像这件事
->decltype(void(begin(r)),void(end(r)))
:P我认为
范围&&
可以是
范围&
@Lingxi:同意,我只是想尽可能与Columbo的代码保持一致,以便两种方法之间的重要差异显而易见。由于强烈的个人偏见,我只在
long
时关闭了varargs:-P由于强烈的个人偏见,我在整个库中使用了
char
int
'
(空格字符):-P干杯<代码>无效(开始(r)),无效(结束(r))可以是
开始(r),无效(结束(r))
。逗号运算符不要求子表达式的类型相同。@Lingxi:如果
begin(r)
返回的类型重载了
运算符,
则没有强制转换,坏事就会发生。