【问题标题】:How to pass an array of zero size to template function如何将零大小的数组传递给模板函数
【发布时间】:2018-03-09 22:51:49
【问题描述】:

我有一个引用数组的示例函数。函数定义中的元素个数未知。

template<typename T, std::size_t N>
void someFun(T (&)[N])
{
    /* ... */
}

为一个元素的数组调用此函数编译正常。 推导出的参数类型为int (&amp;)[1]

int main()
{
    int arr[1];
    someFun(arr);
}

问题是,当我试图传递一个零元素数组时。下面的示例显示了代码和错误。

int main()
{
    int arr[0];
    someFun(arr);
}

编译错误(使用g++ 7.2):

../src/main.cpp: In function 'int main()':
../src/main.cpp:24:13: error: no matching function for call to 'someFun(int  [0])'
someFun(arr);
         ^
../src/main.cpp:9:6: note: candidate: template<class T, long unsigned int N>  void someFun(T (&)[N])
void someFun(T (&a)[N])
  ^~~~~~~
../src/main.cpp:9:6: note:   template argument deduction/substitution failed:
make: *** [src/main.o] Error 1

我假设推导的模板参数类型是int (&amp;)[0],但是这个参数的替换失败了。我可以重载someFun。这是我的工作示例:

template<typename T, std::size_t N>
void someFun(T (&)[N])
{
    /* ... */
}

template<typename T>
void someFun(T (&)[0])
{
    /* ... */
}

int main()
{
    int arr[0];
    someFun(arr);
}

运行此代码会导致调用void someFun(T (&amp;)[0]) 函数并推断出参数类型为int (&amp;)[0]。您能否解释一下为什么我不能对零元素数组使用更通用的解决方案?请不要判断此代码​​的原因。这只是用于学习目的的示例。

【问题讨论】:

  • 注意arrays of zero size are an extension and not standard C++ 使用-pedantic 获取诊断。它们主要用于灵活的数组成员,在其他情况下它们可能会意外工作。
  • 没有大小为 0 的数组。长度必须大于 0 (cppreference)
  • c 样式数组的大小不能为零;这是未定义的行为。
  • @max66 这是 not 未定义的行为,标准 C++ 根本不允许,编译器会给你诊断。
  • 我很惊讶没有人提到这一点,但 std::array 定义为零大小。老实说,无论如何你都不应该使用std::array,仍然没有什么理由继续使用 C 风格的数组。

标签: c++ arrays templates template-argument-deduction


【解决方案1】:

大小为零的数组绝对不是标准的 C++。来自[dcl.array]

T D 的声明中,D 的格式为

D1 [ <em>constant-expression</em><sub>opt</sub> ] <em>attribute-specifier-seq</em><sub>opt</sub>

[...]

如果常量表达式存在,它应该是std​::​size_­t类型的转换常量表达式,并且它的值应该大于零。

然而,GCC 提供了长度为零的数组作为extension,但由于它们是非标准的,您不能期望它们与其他语言功能一起使用,例如模板参数推导。您可以对零长度数组的函数进行显式重载。

#include <cstdlib>

template<typename T, std::size_t N>
void someFun(T (&)[N]) {}

template<typename T>
void someFun(T (&)[0]) {}

int main() {
    int arr[0];
    someFun(arr);
}

这可以在 GCC (7.2.0) 上编译,但不能在 Clang (6.0.0) 上编译。

【讨论】:

  • @DOUGLASO.MOEN 这当然是一个选项,但问题是关于数组,而不是std::array。来自问题:“这只是一个学习目的的例子。”
猜你喜欢
  • 2018-11-19
  • 2018-04-25
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 2014-03-11
  • 1970-01-01
  • 2021-09-27
相关资源
最近更新 更多