Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++ 这段代码发生了什么?_C++_Templates_Android Ndk - Fatal编程技术网

C++ 这段代码发生了什么?

C++ 这段代码发生了什么?,c++,templates,android-ndk,C++,Templates,Android Ndk,我正在尝试使用Android AOSP键盘源代码作为模型来开发Android键盘。有相当一部分JNI代码,我的C++有点生锈,而且我对于宏定义如下的定义有麻烦:NeleMe>/Cux: // Disclaimer: You will see a compile error if you use this macro against a variable-length array. // Sorry for the inconvenience. It isn't supported. templa

我正在尝试使用Android AOSP键盘源代码作为模型来开发Android键盘。有相当一部分JNI代码,我的C++有点生锈,而且我对于宏定义如下的定义有麻烦:NeleMe>/Cux:

// Disclaimer: You will see a compile error if you use this macro against a variable-length array.
// Sorry for the inconvenience. It isn't supported.
template <typename T, int N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#define NELEMS(x) (sizeof(ArraySizeHelper(x)))
所以我想知道这里是否发生了其他事情

我希望您能解释一下这段代码应该做什么,并指导我如何处理编译错误

编辑:我正在通过Android Studio 1.3 RC 3、Android NDK r10e和Gradle 2.5进行编译。编译使用各种工具链(如中所述)。奇怪的是,上面的代码现在可以正确编译和执行(也许它总是正确的)。然而,Android studio仍然会在该行显示一个错误。它还会在每次使用
NELEMS
时显示一个错误:

// Disclaimer: You will see a compile error if you use this macro against a variable-length array.
// Sorry for the inconvenience. It isn't supported.
template <typename T, int N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#define NELEMS(x) (sizeof(ArraySizeHelper(x)))
宏替换后出错:参数太多,应为0


我现在认为这是一个IDE代码分析错误,而不是编译器或编码问题。我最初的问题是关于代码本身的,所以我将此线程标记为已回答。我将打开另一个关于IDE问题的问题。谢谢大家的解释

代码的目的是安全地获取可在编译时使用的数组大小,例如作为新原始(非动态)数组的大小

简单的定义

#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
…是不安全的,因为您可以传递指向它的指针,并返回一个无意义的大小

所以你的代码

template <typename T, int N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#define NELEMS(x) (sizeof(ArraySizeHelper(x)))

与Visual C++ 2015和明文64 G++5.1.0


1) C++14§5.19/2“条件表达式
e
是一个核心常量表达式,除非按照 抽象机器(1.9)将计算以下表达式之一:[…]-引用引用类型的变量或数据成员的id表达式,除非该引用具有前面的初始化,并且 -它是用常量表达式或 -它是对象的非静态数据成员,其生存期开始于
e
;”的计算范围内。”

代码的目的是安全地获取可在编译时使用的数组大小,例如作为新原始(非动态)数组的大小

简单的定义

#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
…是不安全的,因为您可以传递指向它的指针,并返回一个无意义的大小

所以你的代码

template <typename T, int N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#define NELEMS(x) (sizeof(ArraySizeHelper(x)))

与Visual C++ 2015和明文64 G++5.1.0


1) C++14§5.19/2“条件表达式
e
是一个核心常量表达式,除非按照 抽象机器(1.9)将计算以下表达式之一:[…]-引用引用类型的变量或数据成员的id表达式,除非该引用具有前面的初始化,并且 -它是用常量表达式或 -它是对象的非静态数据成员,其生存期开始于
e
;”的计算范围内。” 这是:

template <typename T, int N>
char (&ArraySizeHelper(T (&array)[N]))[N];
这要容易理解得多。并且不需要宏。

这:

template <typename T, int N>
char (&ArraySizeHelper(T (&array)[N]))[N];

这要容易理解得多。不需要一个宏。

你尝试的第二种方式,并考虑它如何工作(但不是你想要的),如果你提供了一个参数的指针,以及如何发出的第一个地址。就第一个问题而言,您可能希望提供您正在使用的C++编译器工具链信息,因为它与过去十年中(几乎)使用的几乎所有C++编译器一起工作。通常让人们首先想到的是,实际的模板函数永远不需要实现,但它仍然可以工作。你到底是如何编译它的?(旧编译器可能在语法上有问题)@ AaltoSks-我使用的是Android NDK提供的标准工具链。第二种方式是尝试和考虑它是如何工作的(但不是你想要的),如果你提供了一个参数的指针,以及第一个地址是如何发出的。就第一个问题而言,您可能希望提供您正在使用的C++编译器工具链信息,因为它与过去十年中(几乎)使用的几乎所有C++编译器一起工作。通常让人们首先想到的是,实际的模板函数永远不需要实现,但它仍然可以工作。你到底是如何编译它的?(较老的编译器可能在语法上有问题。)@AlanStokes-我使用的是Android NDK提供的标准工具链。我同意今天对
constexpr
的评估。唉,OP帖子的几乎所有用法(我第一次在MSATL3.1中看到它)都是在它成为语言特性之前很久才出现的。(例如:你的简化不会在VS2008上编译;OP的第一个代码片段会编译。)
constepr
代码看起来不错,但没有用,因为标准禁止你传递实际参数(左值)。愚蠢的对!@Cheers-Sandhth.-Alf这个简单很糟糕,因为我真的很喜欢这种简化。@Cheers-Sandhth.-Alf
template struct TD;constexpr int x[42]{};TD-t在gcc和clang上编译。@Barry:我不得不研究一下,但我现在用C++14中的相关引用更新了我的答案(N3936最终草案,§5.19/2)。我不能用Visual C++和G++来复制,但也许CLANG有问题。但是我记得它的原因是我曾经在这里发布过正式的无效代码,所以,与您发布的代码完全相同,除了没有不必要的
size\t
;-),有人向我指出了这一点。我同意今天对
constexpr
的评估。唉,OP帖子的几乎所有用法(我第一次在MSATL3.1中看到它)都是在它成为语言特性之前很久才出现的。(例如:你的简化不会在VS2008上编译;OP的第一个代码片段会编译。)
constepr
代码看起来不错,但没有用,因为标准禁止你传递实际参数(左值)。愚蠢的对!@干杯-如果那平原很糟糕,