【问题标题】:Using size of one array in another array在另一个数组中使用一个数组的大小
【发布时间】:2010-09-30 13:48:40
【问题描述】:
// sizeofarray.cpp
#include <iostream>
template <typename T,int N>
int size(T (&Array)[N])
{
  return N;
}

int main()
{
   char p[]="Je suis trop bon, et vous?";
   char q[size(p)]; // (A)
   return 0;
}

听说 C++ 中的数组大小必须是常量表达式。所以char q[size(p)] 无效,对吗?但是我尝试时没有错误

 g++ -Wall sizeofarray.cpp

为什么?

【问题讨论】:

  • q[sizeof(p)] 很好,你的意思可能是q[size(p)]。请注意,后者将在 C++0x 中生效(如果您将 size 声明为 constexpr)。
  • 问题在于“大小”而不是 sizeof。看我的帖子。
  • 尝试编译器选项 -pedantic 或 -std=c++98 ;-)

标签: c++ arrays templates size


【解决方案1】:

就像Prasoon says,它不是一个常量表达式。现在,您可以获得数组大小的常量表达式值,如下所示:

template <std::size_t N>
struct type_of_size
{
    typedef char type[N];
};

template <typename T, std::size_t Size>
typename type_of_size<Size>::type& sizeof_array_helper(T(&)[Size]);

#define sizeof_array(pArray) sizeof(sizeof_array_helper(pArray))

解释here。你基本上把数组的大小编码成一个类型的大小,然后得到那个类型的sizeof,给你:

char q[sizeof_array(p)];

【讨论】:

    【解决方案2】:

    听说C++中的数组大小必须是常量表达式。

    正确

    所以 char q[size(p)] 无效,对吗?

    根据 ISO C++,是的!

    但我尝试时没有错误

    g++ -Wall sizeofarray.cpp

    这是因为 g++ 支持 VLA (Variable Length Array) 作为扩展。

    C++0x 中有constexpr 功能,您可以借助它编写代码

    constexpr int size(T (&Array)[N])
    {
      return N;
    }
    

    然后char q[size(p)] 将是合法的。

    编辑:另请阅读this 文章[博客随便]

    【讨论】:

    • 肯定 sizeof 是一个常量表达式(至少对于标准 C++ 甚至没有的非 vla 而言)?
    【解决方案3】:

    我不同意这里的所有答案。除了一个小问题(绝对不是 VLA)之外,代码显示非常好

    template <typename T,int N> 
    int size(T (&Array)[N]) 
    { 
      return N; 
    } 
    
    int main() 
    { 
       char p[]="Je suis trop bon, et vous?"; 
       char q[sizeof(p)]; // (A), not sizeof and not size as in OP
       return 0; 
    } 
    

    我想知道 sizeof 的结果总是一个 const 值,因此代码应该没问题。

    以上代码在 VS 2010 和 Comeau(严格模式)上构建良好

    $5.3.3/6- "结果是一个常数 输入 size_t。 [注:size_t 已定义 在标准标题 (18.1) 中。”

    【讨论】:

    • 我认为他的意思可能是char q[size(p)]。我已在 OP 中进行了必要的更正。
    【解决方案4】:

    我使用 g++ 4.4.3 并具有以下别名,因此我永远不会忘记打开警告:

    $ alias g++
    alias g++='g++ -ansi -pedantic -Wall -W -Wconversion -Wshadow -Wcast-qual -Wwrite-strings'
    

    如果使用上述编译,会有一些警告。以下步骤显示了不同的选项如何显示不同的警告。

    没有警告选项的编译不会显示任何警告

    $ \g++ sizeofarray.cpp 
    

    开启-Wall

    $ \g++ -Wall sizeofarray.cpp
    sizeofarray.cpp: In function ‘int main()’:
    sizeofarray.cpp:12: warning: unused variable ‘q’
    

    开启-Wextra

    $ \g++ -Wall -Wextra sizeofarray.cpp 
    sizeofarray.cpp: In function ‘int main()’:
    sizeofarray.cpp:12: warning: unused variable ‘q’
    sizeofarray.cpp: At global scope:
    sizeofarray.cpp: In instantiation of ‘int size(T (&)[N]) [with T = char, int N = 27]’:
    sizeofarray.cpp:12:   instantiated from here
    sizeofarray.cpp:4: warning: unused parameter ‘Array’
    

    终于打开-pedantic 发现真正的问题

    $ \g++ -Wall -Wextra -pedantic  sizeofarray.cpp 
    sizeofarray.cpp: In function ‘int main()’:
    sizeofarray.cpp:12: warning: ISO C++ forbids variable length array ‘q’
    sizeofarray.cpp:12: warning: unused variable ‘q’
    sizeofarray.cpp: At global scope:
    sizeofarray.cpp: In instantiation of ‘int size(T (&)[N]) [with T = char, int N = 27]’:
    sizeofarray.cpp:12:   instantiated from here
    sizeofarray.cpp:4: warning: unused parameter ‘Array’
    

    【讨论】:

      猜你喜欢
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 2020-02-19
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      • 1970-01-01
      • 2017-07-02
      相关资源
      最近更新 更多