具有非size_t整数的std :: array的C++模板参数推导

hiv*_*ert 6 c++ arrays integer c++11 template-argument-deduction

我正在尝试根据我的需要调整在可变参数模板函数避免使用struct的解决方案.但是,我无法理解G ++的行为.考虑以下功能:

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

然后是电话

 nextline(std::array<int, 2> { 1,0 });
Run Code Online (Sandbox Code Playgroud)

与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>’
Run Code Online (Sandbox Code Playgroud)

但是如果我更改unsigned Sizeunsigned long Size或匹配则匹配size_t.我不太清楚这里发生了什么.是不是将Size调用中的参数std::array<T, Size>转换为size_t

tex*_*uce 9

std::array 被模板化为:

template<class T, std::size_t N > struct array;
Run Code Online (Sandbox Code Playgroud)

虽然大小N是必须的类型size_t.但是在你的函数中,你传递的是unsigned(int),它不能被解释为size_t.根据SFINAE,如果模板不能被扣除,则它不存在,因此您的模板化功能不存在.

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

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

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

nextline(std::array<int, 2ul> { 1,0 });
Run Code Online (Sandbox Code Playgroud)

它仍然有效,因为它可以扣除和铸造.


dyp的其他解释:

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