热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

是否可以将固定大小的数组作为函数参数就地构造?

如何解决《是否可以将固定大小的数组作为函数参数就地构造?》经验,为你挑选了1个好方法。

这主要是关于与固定大小的数组相关的C++语法的一个问题.

假设我有一个利用类型信息的函数,例如:

template void fun(T const& t){
    std::cout <

我可以传递一个值或一个临时对象:

int i;
fun(i); // prints "int" ("i" actually)
fun(int{});   // prints "int" ("i" actually)

但是我不能对数组做同样的事情

double a[10][10];
fun(a); // ok, prints "a[10][10]" ("A10_A10_d" actually)

fun(double[10][10]); // doesn't compile
fun(double{}[10][10]); // doesn't compile
fun(double[10][10]{}); // doesn't compile
fun(double()[10][10]); // doesn't compile
fun(double[10][10]()); // doesn't compile
fun(double(&)[10][10]); // doesn't compile
fun(double(*)[10][10]); // doesn't compile

我原则上可以这样做:

typedef double a1010[10][10];
fun(a1010{});

但是,有没有预先定义一个typedef呢?

是否有可能将一个固定大小的数组作为函数参数就地构造?

完整代码:

template void fun(T const& t){
    std::cout <


奖励积分(可能是赏金):可变大小的阵列怎么样?

int N = 10;
f(double[N]);

Michael Veks.. 5

尝试:

fun((int[3]){1,2,3});
fun((int[5]){});

至于"奖励积分":可变大小的数组不是语言的一部分.此语言的扩展名不适用于模板参数:

prog.cc:4:6:注意:候选模板被忽略:替换失败:可变修改类型'int [n]'不能用作模板参数fun(const T&t)

编辑

正如Chris所指出的,上述解决方案建议使用复合文字,它是C++的扩展.有一个解决方案,使用一个简单的帮助器类来避免对C++的这种扩展:

template 
struct my_array
{
    T data[N];
};

template 
void print(const T (&x)[N])
{
     for (auto i: x)
         std::cout <{9,10,11}.data);
}

这种方法效果很好,但需要向my_array添加模板参数,这些参数不是推导出来的.使用C++ 17,可以自动推断类型和大小:

template 
struct my_array
{
    constexpr my_array(std::initializer_list x)
    {
       std::size_t i = 0;
       for (auto val : x)
           data[i++] = val;
    }
    T data[N];
};
template 
my_array(T...) -> my_array::type, sizeof...(T)>;

int main()
{
    print(my_array{9,10,11}.data);
}

对于二维数组,这稍微复杂一些:

template 
struct my_array2d
{
    constexpr my_array2d(std::initializer_list > x)
    {
        std::size_t i = 0;
        for (const auto & row : x) {
            int j=0;
            for (const auto & val: row) {
                data[i][j++] = val;
            }
            i++;
        }
    }
    T data[N1][N2];
};
int main()
{
    work(my_array2d{{9,1},{10,2},{11,3}}.data);
}

我已经放弃了二维阵列的演绎指南,但我相信它们是可能的.



1> Michael Veks..:

尝试:

fun((int[3]){1,2,3});
fun((int[5]){});

至于"奖励积分":可变大小的数组不是语言的一部分.此语言的扩展名不适用于模板参数:

prog.cc:4:6:注意:候选模板被忽略:替换失败:可变修改类型'int [n]'不能用作模板参数fun(const T&t)

编辑

正如Chris所指出的,上述解决方案建议使用复合文字,它是C++的扩展.有一个解决方案,使用一个简单的帮助器类来避免对C++的这种扩展:

template 
struct my_array
{
    T data[N];
};

template 
void print(const T (&x)[N])
{
     for (auto i: x)
         std::cout <{9,10,11}.data);
}

这种方法效果很好,但需要向my_array添加模板参数,这些参数不是推导出来的.使用C++ 17,可以自动推断类型和大小:

template 
struct my_array
{
    constexpr my_array(std::initializer_list x)
    {
       std::size_t i = 0;
       for (auto val : x)
           data[i++] = val;
    }
    T data[N];
};
template 
my_array(T...) -> my_array::type, sizeof...(T)>;

int main()
{
    print(my_array{9,10,11}.data);
}

对于二维数组,这稍微复杂一些:

template 
struct my_array2d
{
    constexpr my_array2d(std::initializer_list > x)
    {
        std::size_t i = 0;
        for (const auto & row : x) {
            int j=0;
            for (const auto & val: row) {
                data[i][j++] = val;
            }
            i++;
        }
    }
    T data[N1][N2];
};
int main()
{
    work(my_array2d{{9,1},{10,2},{11,3}}.data);
}

我已经放弃了二维阵列的演绎指南,但我相信它们是可能的.


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
author-avatar
竹叶清2012
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有