【问题标题】:C++ template parameter deduction for std::array with non size_t integer具有非 size_t 整数的 std::array 的 C++ 模板参数推导
【发布时间】:2014-03-11 13:02:57
【问题描述】:

我正在尝试根据我的需要调整Avoiding struct in variadic template function 中提出的解决方案。但是,我无法理解 G++ 的行为。考虑以下函数:

 template <typename T, unsigned Size>
 int nextline(const typename std::array<T, Size> ar) {
    return 0;
 }

然后调用

 nextline(std::array<int, 2> { 1,0 });

与抱怨的 GCC 不匹配

eslong.cpp: In function ‘int main()’:
eslong.cpp:10:38: error: no matching function for call to ‘nextline(std::array<int, 2ul>)’
   nextline(std::array<int, 2> { 1,0 });
                                      ^
eslong.cpp:10:38: note: candidate is:
eslong.cpp:4:5: note: template<class T, unsigned int Size> int nextline(std::array<T, Size>)
 int nextline(const typename std::array<T, Size> ar) {
     ^
eslong.cpp:4:5: note:   template argument deduction/substitution failed:
eslong.cpp:10:38: note:   mismatched types ‘unsigned int’ and ‘#‘integer_cst’ not supported by dump_type#<type error>’
   nextline(std::array<int, 2> { 1,0 });
                                      ^
eslong.cpp:10:38: note:   ‘std::array<int, 2ul>’ is not derived from ‘std::array<T, Size>’

但是,如果我将 unsigned Size 更改为 unsigned long Sizesize_t,它会匹配。我不确定这里发生了什么。对std::array&lt;T, Size&gt;的调用中的Size参数不是转换成size_t了吗?

【问题讨论】:

  • 它对我来说编译得很好:ideone.com/1FEmgZ
  • 1) typename 在这里是错误的 (const typename std::array....)。 2)需要完全匹配非类型模板参数的类型,见[temp.deduct.type]/17。

标签: c++ arrays c++11 integer template-argument-deduction


【解决方案1】:

std::array 被模板化为:

template<class T, std::size_t N > struct array;

N 的大小必须是size_t 类型。但是在你的函数中,你传递了一个无符号(int),它不能被解释为size_t。根据SFINAE如果一个模板不能推导出来就是不存在的,那么你的模板化函数就不存在了。

这不是调用行的问题,而是您对函数模板的声明。要更正此问题,请使用正确的类型:

template <typename T, size_t Size>
int nextline(const typename std::array<T, Size> ar) {
  return 0;
 }

在这种情况下,即使您使用:

nextline(std::array<int, 2ul> { 1,0 });

它仍然有效,因为它可以被推断和转换。


dyp的补充说明:

[temp.deduct.type]/17 用于非类型模板参数,要求推导事物的类型(模板参数)与模板参数的类型相同被推导出来。

【讨论】:

    【解决方案2】:

    您的文字2 被解释为unsigned long,但您将Size 模板声明为unsigned int。改用这个:

    template <typename T, size_t Size>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-22
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 2015-05-19
      • 1970-01-01
      • 2021-06-16
      相关资源
      最近更新 更多